////////////////////////////////////////////////////////////////////////////////////////////////////

#include "CUserInterface.h"
#include "CLevelEditor.h"
#include "CEffect.h"
#include "CGUIFileSaveDialog.h"
#include "CGUITreeCtrl.h"
#include "CListBox.h"
#include "CPlaneCamera.h"
#include "DoUndoCommands.h"
#include "CEventReceiver.h"
#include "CProperty.h"
#include "IGUIEnvironment.h"
#include "IGUIWindow.h"
#include "IGUITabControl.h"
#include "IGUIContextMenu.h"
#include "IGUIComboBox.h"
#include "IGUIStaticText.h"
#include "IGUICheckBox.h"
#include "IGUICinematicCtrl.h"
#include "IGUIFont.h"
#include "IBillboardSceneNode.h"
#include "IGUIFontBitmap.h"
#include "CMultiCommand.h"
#include "CSetVisibleCommand.h"
#include "CMoveCommand.h"
#include "CRotateCommand.h"
#include "CScaleCommand.h"
#include "CSetColorCommand.h"
#include "CSetSizeCommand.h"
#include "CSetNameCommand.h"
#include "CSetColorAttributeCommand.h"
#include "CSetStringAttributeCommand.h"
#include "CSetBoolAttributeCommand.h"
#include "CSetMaterialTypeCommand.h"
#include "CSetIntAttributeCommand.h"
#include "CSetMeshFileCommand.h"
#include "CSetAnimationFileCommand.h"
#include "CSetTextureCommand.h"
#include "CSetTriPrismParamsCommand.h"
#include "ICameraSceneNode.h"
#include "IWriteFile.h"
#include <windows.h> 
#include <shellapi.h>
#include "IXMLWriter.h"
#include <assert.h>
#include "CCinematicThread.h"

#include "FpsSceneManager.h"
#include "lib2d\SpriteManager.h"
#include "lib2d\Sprite.h"

#include "IlluminationMap\PFExporter.h"

extern CLevelEditor* editor;

CUserInterface::CUserInterface()
{		
	m_bTerrainLoaded = false;
	m_ToolsWindow = 0;
	m_PropertiesWindow = 0;
	m_SceneGraphWindow = 0;
	m_HistoryWindow = 0;
	m_LevelProperties = 0;
	m_PFExporterWindow = 0;
	m_SceneGraphPropertiesWindow = 0;
	m_UserBrowsePath = g->device->getFileSystem()->getWorkingDirectory();
	m_LastScreenSize = g->driver->getScreenSize();
	m_bQuitAfterSave = false ;

	m_bUseEditorRelativePath = false;

	m_PSTabs = NULL;

	m_linkChangedProp = NULL;
}

CUserInterface::~CUserInterface()
{
/*	//Save windows positions
	IXMLWriter* xml = g->device->getFileSystem()->createXMLWriter("editor_config.xml");
	IAttributes* attr = g->device->getFileSystem()->createEmptyAttributes();

	if (!xml)
		return;
//TODO: Save main window position	
	attr->addPosition2d("ToolsPosition", m_ToolsWindow->getRelativePosition().UpperLeftCorner);
	attr->addBool("ToolsVisible", m_ToolsWindow->isVisible());

	attr->addPosition2d("PropertiesPosition", m_PropertiesWindow->getRelativePosition().UpperLeftCorner);
	attr->addBool("PropertiesVisible", m_PropertiesWindow->isVisible());

	attr->addPosition2d("TreeViewPosition", m_SceneGraphWindow->getRelativePosition().UpperLeftCorner);
	attr->addBool("TreeViewVisible", m_SceneGraphWindow->isVisible());

	attr->write(xml, true);

	xml->drop();
*/
}

int CUserInterface::init()
{
	m_Clipboard = NULL;
	m_oldSearchBoxText = L"";

	m_startupDir = g->device->getFileSystem()->getWorkingDirectory();
	loadRecentFiles();

	createMainMenu();
	createToolsWindow();	
	createPropertiesWindow();
	createSceneGraphWindow();
	createHistoryWindow();	
	createLevelProprtiesWindow();

	m_copyedEffectIndex = -1;
	m_copyedPsIndex = -1;

/*
//read window positions

	IXMLReader* xml = g->device->getFileSystem()->createXMLReader("editor_config.xml");
	IAttributes* attr = g->device->getFileSystem()->createEmptyAttributes();

	if (!xml)
		return 0;
	
	while (xml->read())
	{
		if (xml->getNodeType() == EXN_ELEMENT &&
			(!wcscmp(L"attributes", xml->getNodeName())))
		{
			attr->read(xml, false);			
		}
	}
	
	rect<s32> rect;

	rect = m_ToolsWindow->getRelativePosition();
	if (attr->findAttribute("ToolsPosition") >= 0)
	{
		rect.UpperLeftCorner = attr->getAttributeAsPosition2d("ToolsPosition");
		m_ToolsWindow->setRelativePosition(rect);
	}
	if (attr->findAttribute("ToolsVisible") >= 0)
		m_ToolsWindow->setVisible(attr->getAttributeAsBool("ToolsVisible"));

	rect = m_PropertiesWindow->getRelativePosition();
	if (attr->findAttribute("PropertiesPosition") >= 0)
	{
		rect.UpperLeftCorner = attr->getAttributeAsPosition2d("PropertiesPosition");
		m_PropertiesWindow->setRelativePosition(rect);
	}
	if (attr->findAttribute("PropertiesVisible") >= 0)
		m_PropertiesWindow->setVisible(attr->getAttributeAsBool("PropertiesVisible"));

	rect = m_SceneGraphWindow->getRelativePosition();
	if (attr->findAttribute("TreeViewPosition") >= 0)
	{
		rect.UpperLeftCorner = attr->getAttributeAsPosition2d("TreeViewPosition");
		m_SceneGraphWindow->setRelativePosition(rect);
	}
	if (attr->findAttribute("TreeViewVisible") >= 0)
		m_SceneGraphWindow->setVisible(attr->getAttributeAsBool("TreeViewVisible"));

	xml->drop();
*/
	return 0;

}

void CUserInterface::createToolsWindow()
{
	if (m_ToolsWindow)
		return;

	m_ToolsWindow = g->guienv->addWindow(rect<s32>(824, 20, 1024, 425), false, L"Tools", 0, WND_ID_TOOLS);	

	m_ToolsTabs = g->guienv->addTabControl(rect<s32>(0, 20, 198, 505), m_ToolsWindow, false, false, TOOLS_TABS);
	m_ToolsTabs->setTabHeight(20);
	m_ToolsTabs->addTab(L"objects");
	m_ToolsTabs->addTab(L"templates");
	m_ToolsTabs->addTab(L"effects");
	m_ToolsObjectsTab = m_ToolsTabs->getTab(0);
	m_ToolsTemplatesTab = m_ToolsTabs->getTab(1);
	m_ToolsEffectsTab = m_ToolsTabs->getTab(2);

	//objects tab
	
	g->guienv->addStaticText(L"Create Objects", rect<s32>(5, 10, 100, 40), false, false, m_ToolsObjectsTab);

	m_searchBoxForObjectList = g->guienv->addEditBox(L"", rect<s32>(30, 40, 190, 60), true, m_ToolsObjectsTab, TOOLS_ID_SERACHBOX);
	m_GameObjectList = g->guienv->addListBox(rect<s32>(30, 65, 190, 235), m_ToolsObjectsTab, TOOLS_ID_PICKLIST, true);
	g->guienv->addButton(rect<s32>(5, 65, 25, 235), m_ToolsObjectsTab, TOOLS_ID_INSERT_GAME_OBJECT, L"+");

	//g->guienv->addButton(rect<s32>(5, 245, 63, 265), m_ToolsObjectsTab, TOOLS_ID_INSERT_CUBE_BTN, L"Cube", 0);
	//g->guienv->addButton(rect<s32>(68, 245, 126, 265), m_ToolsObjectsTab, TOOLS_ID_INSERT_SPHERE_BTN, L"Sphere", 0);
	//g->guienv->addButton(rect<s32>(131, 245, 190, 265), m_ToolsObjectsTab, TOOLS_ID_INSERT_TERRAIN_BTN, L"Terrain", 0);
	//g->guienv->addButton(rect<s32>(131, 245, 190, 265), m_ToolsObjectsTab, TOOLS_ID_INSERT_NAVMESH_BTN, L"NavMesh", 0);
	
	//g->guienv->addButton(rect<s32>(5, 270, 63, 290), m_ToolsObjectsTab, TOOLS_ID_INSERT_SKYBOX_BTN, L"Skybox", 0);
	//g->guienv->addButton(rect<s32>(68, 270, 126, 290), m_ToolsObjectsTab, TOOLS_ID_INSERT_CAMERA_BTN, L"Camera", 0);
	//g->guienv->addButton(rect<s32>(131, 270, 190, 290), m_ToolsObjectsTab, TOOLS_ID_INSERT_BILLBOARD_BTN, L"Billboard", 0);

	//g->guienv->addButton(rect<s32>(5, 295, 95, 315), m_ToolsObjectsTab, TOOLS_ID_INSERT_STATIC_MESH_BTN, L"Static Mesh", 0);
	//g->guienv->addButton(rect<s32>(100, 295, 190, 315), m_ToolsObjectsTab, TOOLS_ID_INSERT_ANIM_MESH_BTN, L"Animated Mesh", 0);

	//g->guienv->addButton(rect<s32>(5, 320, 95, 340), m_ToolsObjectsTab, TOOLS_ID_INSERT_GEOMETRY_BTN, L"Room", 0);
	//g->guienv->addButton(rect<s32>(100, 320, 190, 340), m_ToolsObjectsTab, TOOLS_ID_INSERT_COLLISIONS_BTN, L"Collisions", 0);

	g->guienv->addStaticText(L"Edit Controls", rect<s32>(5, 245, 100, 265), false, false, m_ToolsObjectsTab);

	//first row: move, rotate, scale
	m_MovePushButton = g->guienv->addButton(rect<s32>(5, 265, 63, 285), m_ToolsObjectsTab, TOOLS_ID_MOVE_BTN, L"Move", 0);
	m_MovePushButton->setIsPushButton(true);
	m_MovePushButton->setPressed(false);

	m_RotatePushButton = g->guienv->addButton(rect<s32>(68, 265, 126, 285), m_ToolsObjectsTab, TOOLS_ID_ROTATE_BTN, L"Rotate", 0);
	m_RotatePushButton->setIsPushButton(true);
	m_RotatePushButton->setPressed(false);

	m_ScalePushButton = g->guienv->addButton(rect<s32>(131, 265, 190, 285), m_ToolsObjectsTab, TOOLS_ID_SCALE_BTN, L"Scale", 0);
	m_ScalePushButton->setIsPushButton(true);
	m_ScalePushButton->setPressed(false);

	//second row: move local, rotate local, modify trigger
	m_MoveLocalPushButton = g->guienv->addButton(rect<s32>(5, 290, 63, 310), m_ToolsObjectsTab, TOOLS_ID_MOVE_LOCAL_BTN, L"MoveLocal", 0);
	m_MoveLocalPushButton->setIsPushButton(true);
	m_MoveLocalPushButton->setPressed(false);

	m_RotateLocalPushButton = g->guienv->addButton(rect<s32>(68, 290, 126, 310), m_ToolsObjectsTab, TOOLS_ID_ROTATE_LOCAL_BTN, L"RotLocal", 0);
	m_RotateLocalPushButton->setIsPushButton(true);
	m_RotateLocalPushButton->setPressed(false);

	m_ModifyPushButton = g->guienv->addButton(rect<s32>(131, 290, 190, 310), m_ToolsObjectsTab, TOOLS_ID_MODIFY_TRIG_BTN, L"ModifyTrig", 0);
	m_ModifyPushButton->setIsPushButton(true);
	m_ModifyPushButton->setPressed(false);	

	//thrid row: correct camera, set camera, copy camera
	m_CorrectCamAreaButton = g->guienv->addButton(rect<s32>(5, 315, 63, 335), m_ToolsObjectsTab, TOOLS_ID_CORRECT_CAMAREA_BTN, L"Crt CamA", 0);
	m_CorrectCamAreaButton->setIsPushButton(false);

	m_SetCameraButton = g->guienv->addButton(rect<s32>(68, 315, 126, 335), m_ToolsObjectsTab, TOOLS_ID_SET_CAMAREA_BTN, L"Set Cam", 0);
	m_SetCameraButton->setIsPushButton(true);
	m_SetCameraButton->setPressed(false);

	m_CopyCameraButton = g->guienv->addButton(rect<s32>(131, 315, 190, 335), m_ToolsObjectsTab, TOOLS_ID_COPY_CAMERA_BTN, L"Copy Cam", 0);
	m_CopyCameraButton->setIsPushButton(false);

	//fourth row
	g->guienv->addButton(rect<s32>(5, 340, 97, 360), m_ToolsObjectsTab, TOOLS_ID_DELETE_BTN, L"Delete Selected", 0);
	g->guienv->addButton(rect<s32>(102, 340, 190, 360), m_ToolsObjectsTab, TOOLS_ID_SNAP2COL_BTN, L"Snap to Collision", 0);

	//templates tab
	g->guienv->addStaticText(L"Create From Template", rect<s32>(5, 20, 150, 50), false, false, m_ToolsTemplatesTab);

	g->guienv->addListBox(rect<s32>(30, 35, 190, 235), m_ToolsTemplatesTab, TOOLS_ID_TEMPLATE_LIST, true);
	g->guienv->addButton(rect<s32>(5, 35, 25, 235), m_ToolsTemplatesTab, TOOLS_ID_INSERT_GAME_TEMPLATE, L"+");

	g->guienv->addButton(rect<s32>(5, 240, 70, 260), m_ToolsTemplatesTab, TOOLS_ID_ADD_TEMPLATE_BTN, L" New From : ", L"");

	g->guienv->addComboBox(rect<s32>(75, 240, 190, 260), m_ToolsTemplatesTab, TOOLS_ID_TEMPLATES_NEW_COMBO);

	g->guienv->addButton(rect<s32>(5, 270, 190, 320), m_ToolsTemplatesTab, TOOLS_ID_SAVE_TEMPLATE_BTN, L" Save Templates ", L"");

	g->guienv->addButton(rect<s32>(5, 330, 190, 350), m_ToolsTemplatesTab, TOOLS_ID_DELETE_TEMPLATE_BTN, L" Delete Template ", L"");

	//effects tab
	g->guienv->addButton(rect<s32>(5, 5, 190, 25), m_ToolsEffectsTab, TOOLS_ID_SAVE_EFFECTS_BTN, L" Save Effects ", L"Save Effects");
	
	g->guienv->addStaticText(L"Effects", rect<s32>(5, 30, 90, 50), false, false, m_ToolsEffectsTab);
	g->guienv->addListBox(rect<s32>(5, 45, 105, 145), m_ToolsEffectsTab, TOOLS_ID_EFFECTS_LIST, true);
	g->guienv->addButton(rect<s32>(5, 150, 25, 170), m_ToolsEffectsTab, TOOLS_ID_ADD_EFFECT_BTN, L" + ", L"Add Effect");
	g->guienv->addButton(rect<s32>(30, 150, 50, 170), m_ToolsEffectsTab, TOOLS_ID_REMOVE_EFFECT_BTN, L" - ", L"Remove Effect");
	g->guienv->addButton(rect<s32>(55, 150, 75, 170), m_ToolsEffectsTab, TOOLS_ID_CLONE_EFFECT_BTN, L" += ", L"Clone Effect");
	g->guienv->addButton(rect<s32>(80, 150, 100, 170), m_ToolsEffectsTab, TOOLS_ID_RESTART_EFFECT_BTN, L" > ", L"Restart Effect");

	g->guienv->addStaticText(L"Particle Systems", rect<s32>(100, 30, 190, 50), false, false, m_ToolsEffectsTab);
	g->guienv->addListBox(rect<s32>(110, 45, 190, 145), m_ToolsEffectsTab, TOOLS_ID_PS_LIST, true);
	g->guienv->addButton(rect<s32>(110, 150, 130, 170), m_ToolsEffectsTab, TOOLS_ID_ADD_PS_BTN, L" + ", L"Add Particle System");
	g->guienv->addButton(rect<s32>(135, 150, 155, 170), m_ToolsEffectsTab, TOOLS_ID_REMOVE_PS_BTN, L" - ", L"Remove Particle System");
	g->guienv->addButton(rect<s32>(160, 150, 180, 170), m_ToolsEffectsTab, TOOLS_ID_CLONE_PS_BTN, L" += ", L"Clone Particle System");
	g->guienv->addButton(rect<s32>(110, 175, 143, 195), m_ToolsEffectsTab, TOOLS_ID_COPY_PS_BTN, L"Copy");
	g->guienv->addButton(rect<s32>(147, 175, 180, 195), m_ToolsEffectsTab, TOOLS_ID_PASTE_PS_BTN, L"Paste");

	m_effectNameBox = g->guienv->addEditBox(L"", rect<s32>(5, 200, 190, 220), true, m_ToolsEffectsTab);
	m_effectNameBox->setAutoScroll(true);	

}

void CUserInterface::createHistoryWindow ()
{
	if (m_HistoryWindow)
		return;

	m_HistoryWindow = g->guienv->addWindow(rect<s32>(0, 768, 230, 968), false, L"History", 0, WND_ID_HISTORY);

	m_HistoryList = g->guienv->addListBox(rect<s32>(5, 25, 225, 195), m_HistoryWindow, HISTORY_ID_LIST, true);
}

void CUserInterface::createPropertiesWindow()
{
	if (m_PropertiesWindow)
		return;

	m_PropertiesWindow = g->guienv->addWindow(rect<s32>(824, 425, 1024, 660), false, L"Properties", 0, WND_ID_PROPERTIES);		
	m_PropertiesTabs = g->guienv->addTabControl(rect<s32>(0, 20, 198, 50), m_PropertiesWindow, false, false, PROP_TABS);
	m_PropertiesTabs->setTabHeight(20);
	m_PropertiesTabs->addTab(L"standard");
	m_PropertiesTabs->addTab(L"custom");
	m_PropertiesStandardTab = m_PropertiesTabs->getTab(0);
	m_PropertiesCustomTab = m_PropertiesTabs->getTab(1);
}

void CUserInterface::createSceneGraphWindow()
{
	if (m_SceneGraphWindow)
		return;

	m_SceneGraphWindow = g->guienv->addWindow(rect<s32>(0, 20, 230, 768), false, L"Scene Graph", 0, WND_ID_SCENEGRAPH);

	m_SceneGraphTabs = g->guienv->addTabControl(rect<s32>(0, 20, 228, 768), m_SceneGraphWindow, false, false, SCENEGRAPH_TABS);
	m_SceneGraphTabs->setTabHeight(20);
	m_SceneGraphTabs->addTab(L"graph");
	m_SceneGraphTabs->addTab(L"visible");
	m_SceneGraphTabs->addTab(L"invisible");
	m_SceneGraphTabs->addTab(L"locked");
	m_SceneGraphTreeTab = m_SceneGraphTabs->getTab(0);
	m_SceneGraphPropertiesVisibleTab = m_SceneGraphTabs->getTab(1);
	m_SceneGraphPropertiesInvisibleTab = m_SceneGraphTabs->getTab(2);
	m_SceneGraphPropertiesLockedTab = m_SceneGraphTabs->getTab(3);
	m_SceneGraphTabs->setActiveTab(0);
	m_SceneGraphPropertiesVisibleList = addCListBox(g->guienv,  rect<s32>(5, 25, 220, 690),m_SceneGraphPropertiesVisibleTab, SCENEGRAPH_VISIBLE_ID_LIST,
		true);

	m_SceneGraphPropertiesInvisibleList = addCListBox(g->guienv,  rect<s32>(5, 25, 220, 690),m_SceneGraphPropertiesInvisibleTab, SCENEGRAPH_INVISIBLE_ID_LIST,
		true);
	
	m_SceneGraphPropertiesLockedList = addCListBox(g->guienv,  rect<s32>(5, 25, 220, 690),m_SceneGraphPropertiesLockedTab, SCENEGRAPH_LOCKED_ID_LIST,
		true);
	m_sceneGraphTree = AddGUITreeCtrl(g->guienv, rect<s32>(5, 25, 220, 690), m_SceneGraphTreeTab, SCENEGRAPH_ID_TREEVIEW);

	g->guienv->addButton(rect<s32>(154, 5, 169, 25), m_SceneGraphTreeTab, SCENEGRAPH_ID_UP, L"U");
	g->guienv->addButton(rect<s32>(171, 5, 186, 25), m_SceneGraphTreeTab, SCENEGRAPH_ID_DOWN, L"D");
	g->guienv->addButton(rect<s32>(188, 5, 203, 25), m_SceneGraphTreeTab, SCENEGRAPH_ID_TOP, L"T");

	g->guienv->addButton(rect<s32>(84, 691, 102, 706), m_SceneGraphTreeTab, SCENEGRAPH_ID_UP, L"^");
	g->guienv->addButton(rect<s32>(104, 691, 122, 706), m_SceneGraphTreeTab, SCENEGRAPH_ID_DOWN, L"!");
	g->guienv->addButton(rect<s32>(124, 691, 142, 706), m_SceneGraphTreeTab, SCENEGRAPH_ID_TOP, L"T");

	m_searchBox = g->guienv->addEditBox(L"", rect<s32>(5, 25, 145, 45), true, m_SceneGraphTabs, SCENEGRAPH_ID_SEARCHBOX);
	g->guienv->addButton(rect<s32>(182, 5, 218, 25), m_SceneGraphPropertiesVisibleTab, VISBLE_LIST_ID_SORT_BTN, L"Sort", 0);

	m_FilterPushButton = g->guienv->addButton(rect<s32>(150, 5, 180, 25), m_SceneGraphPropertiesVisibleTab, VISBLE_LIST_ID_FILTER_BTN, L"Filter", 0);
	m_FilterPushButton->setIsPushButton(true);
	m_FilterPushButton->setPressed(false);
}

void CUserInterface::showSaveWarning()
{
	g->device->getGUIEnvironment()->addMessageBox(
		L"Scene has modifications ! " , L" Save scene ? " , true , EMBF_YES | EMBF_NO, 0, MSG_BOX_SAVE_SCENE );
}

void CUserInterface::showAutosaveWarning()
{
	g->device->getGUIEnvironment()->addMessageBox(
		L"Load Autosave " , L"Last time application was not close normal.\nWould you like to load level from autosave ? " , true , EMBF_YES | EMBF_NO, 0, MSG_BOX_AUTOSAVE_SCENE );
}

void CUserInterface::showAboutBox()
{
	g->device->getGUIEnvironment()->addMessageBox(
		L"ShrekLicht Editor About", L"Version 0.6.2\nCopyright (C) 2009 Gameloft\nAuthor: Svilen Stoyanov\nProgramming: Mirolyub Hristov, Stefan Dobrev, Sonya Valkova\nFPS MOD Nicolae Stancu , Mihai Sebea , Andi George Matei\nBeijing Gameloft.");
}

void CUserInterface::showControlsHelpBox()
{
	g->device->getGUIEnvironment()->addMessageBox(L"ShrekLicht Editor Controls",
		L"Select - Left mouse button. Multi select - Ctrl.\nWhen object is selected, hold button and move mouse to change.\nButton [X] - Edit by X axis.\nButton [C] - Edit by Y axis.\nButton [Z] - Edit by Z axis.\nButton [A] - Edit by all axels.");
}

void CUserInterface::update()
{
	if (m_sceneGraphTree)
	{
		m_sceneGraphTree->SetSearchText(m_searchBox->getText());
	}

	if( m_GameObjectList )
	{
		irr::core::stringw txt =  m_searchBoxForObjectList->getText();
		if( txt.size() >0 )
		{
			if( m_oldSearchBoxText != txt )
			{
				m_oldSearchBoxText = txt;
				m_GameObjectList->clear();
				int count = m_allGameObject.size();
				irr::core::stringw txtNoCase = txt;
				txtNoCase.make_lower();
				for(int i=0;i<count;i++)
				{
					irr::core::stringw itemText = m_allGameObject[i];
					itemText.make_lower();
					if( itemText.find( txtNoCase.c_str() ) != -1)
					{
						m_GameObjectList->addItem( m_allGameObject[i].c_str() );
					}
				}
			}
		}
		else
		{
			if( m_GameObjectList->getItemCount() != m_allGameObject.size() )
			{
				m_GameObjectList->clear();
				int count = m_allGameObject.size();
				for(int i=0;i<count;i++)
				{
					m_GameObjectList->addItem( m_allGameObject[i].c_str() );
				}
			}
		}		
	}
	if (m_SceneGraphPropertiesVisibleList)
	{
		((CListBox*)m_SceneGraphPropertiesVisibleList)->SetSearchText(m_searchBox->getText());

		IGUIListBox* listBox = (IGUIListBox*)m_ToolsObjectsTab->getElementFromId(TOOLS_ID_PICKLIST);
		if (listBox->getSelected() < 0 || !m_FilterPushButton->isPressed())
		{
			((CListBox*)m_SceneGraphPropertiesVisibleList)->SetGameText("");
		}
		else if(m_FilterPushButton->isPressed())
		{
			((CListBox*)m_SceneGraphPropertiesVisibleList)->SetGameText(editor->m_GameObjects[listBox->getSelected()]->m_Attributes->getAttributeAsString("!GameType"));
		}	
	}
	if (m_SceneGraphPropertiesInvisibleList)
	{
		((CListBox*)m_SceneGraphPropertiesInvisibleList)->SetSearchText(m_searchBox->getText());
	}
	if (m_SceneGraphPropertiesLockedList)
	{
		((CListBox*)m_SceneGraphPropertiesLockedList)->SetSearchText(m_searchBox->getText());
	}	
}

bool CUserInterface::receiveEvent(const SEvent& event)
{
	switch (event.GUIEvent.EventType)
	{
	case EGET_MESSAGEBOX_OK:
		{
			IGUIElement* messageBox = event.GUIEvent.Caller;
			assert(messageBox);
			if(messageBox->getID() == WND_ID_RENAME_THREAD)
			{
				IGUIElement* editBox = messageBox->getElementFromId(WND_ID_EDIT_RENAME_THREAD, true);
				assert(editBox);
				
				IGUICinematicCtrl* cinematicCtrl = m_CinematicEditor.GetCinematicCtrl();
				assert(cinematicCtrl);

				cinematicCtrl->SetSelectedText(editBox->getText());

				CCinematicThread* cinematicThread = static_cast<CCinematicThread*>(cinematicCtrl->GetSelectedData());
				assert(cinematicThread);

				cinematicThread->m_Name = editBox->getText();
				cinematicCtrl->SetSelectedData(static_cast<void*>(cinematicThread));
			}
			return true;
		}
		case EGET_TAB_CHANGED:
			{
				switch (event.GUIEvent.Caller->getID())
				{
					case TOOLS_TABS:
						{
							IGUITabControl* w = (IGUITabControl*)event.GUIEvent.Caller;
							s32 active = w->getActiveTab();
							if (active == 2) //effects tab visible
							{
								IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
								editor->SetEffectVisible(lb->getSelected(), true);
							}
							else // effects tab invisible
							{
								editor->SetEffectVisible(-1, false);

								//update all level effects
								for (u32 i = 0; i < editor->m_SceneObjects.size(); i ++)
								{
									CSceneObject* pObj = editor->m_SceneObjects[i];
									if (pObj->m_UserData->getAttributeAsString("!GameType") == stringc("Effect"))
									{
										editor->SetObjectEffectType(pObj->m_SceneNode, pObj->m_UserData->getAttributeAsStringW("$EffectType"));
									}
									else if (pObj->m_UserData->getAttributeAsString("!GameType") == stringc("EffectDemage"))
									{
										editor->SetObjectEffectType(pObj->m_SceneNode, pObj->m_UserData->getAttributeAsStringW("$EffectType"));
									}
								}
							}
						}
					case SCENEGRAPH_TABS:
						{
							((CListBox*)m_SceneGraphPropertiesVisibleList)->setSelected(-1);
							((CListBox*)m_SceneGraphPropertiesInvisibleList)->setSelected(-1);
							((CListBox*)m_SceneGraphPropertiesLockedList)->setSelected(-1);							
							m_sceneGraphTree->SetSelected(0);
							break;

							//IGUITabControl* w = (IGUITabControl*)event.GUIEvent.Caller;
							//int active = w->getActiveTab();
							//array<TreeNode*> Selected = m_sceneGraphTree->GetSelected();
							//switch(active)
							//{
							//	case 1:
							//		if(Selected.size()>0)
							//		{
							//			((CListBox*)m_SceneGraphPropertiesVisibleList)->SelectedList.clear();
							//			for (int i = 0; i < Selected.size(); i++)
							//				((CListBox*)m_SceneGraphPropertiesVisibleList)->setSelected(Selected[i]->Text.c_str());
							//		}
							//		else
							//			((CListBox*)m_SceneGraphPropertiesVisibleList)->setSelected(-1);
							//	break;
							//	case 2:
							//		if(Selected.size()>0)
							//		{
							//			((CListBox*)m_SceneGraphPropertiesInvisibleList)->SelectedList.clear();
							//			for (int i = 0; i < Selected.size(); ++i)
							//				((CListBox*)m_SceneGraphPropertiesInvisibleList)->setSelected(Selected[i]->Text.c_str());
							//		}
							//		else
							//			((CListBox*)m_SceneGraphPropertiesInvisibleList)->setSelected(-1);
							//	break;
							//	case 3:
							//		if(Selected.size()>0)
							//		{
							//			((CListBox*)m_SceneGraphPropertiesLockedList)->SelectedList.clear();
							//			for (int i = 0; i < Selected.size(); ++i)
							//				((CListBox*)m_SceneGraphPropertiesLockedList)->setSelected(Selected[i]->Text.c_str());
							//		}
							//		else
							//			((CListBox*)m_SceneGraphPropertiesLockedList)->setSelected(-1);
							//	break;
							//}
						}
						break;
				}
			}
			break;

		case EGET_LISTBOX_CHANGED:
			{
				switch (event.GUIEvent.Caller->getID())
				{
					case TOOLS_ID_EFFECTS_LIST:
						{
							IGUIListBox* lb = (IGUIListBox*)event.GUIEvent.Caller;
							IGUIListBox* lb_ps = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
							lb_ps->clear();

							int sel = lb->getSelected();

							if (sel != -1)
							{
								for (u32 i=0; i < editor->m_Effects[sel]->m_ParticleSystems.size(); i++)
								{
									stringw name = stringw(editor->m_Effects[sel]->m_ParticleSystems[i]->getName());
									lb_ps->addItem(name.c_str());
								}

								editor->SetEffectVisible(sel, true);

								m_effectNameBox->setText(editor->m_Effects[sel]->m_effectName.c_str());
							}							
							else
							{
								m_effectNameBox->setText(L"");
							}

							createSelectedPSProperties();
						}
						break;

					case TOOLS_ID_PS_LIST:
						createSelectedPSProperties();
						break;

					case TOOLS_ID_AFFECTORS_LIST:
						createSelectedAffectorProperties();
						break;

					case TOOLS_ID_TEMPLATE_LIST:
						createSelectedTemplateProperties();
						break;
				}
			}
			break;

		case EGET_LISTBOX_SELECTED_AGAIN:
			switch (event.GUIEvent.Caller->getID())
			{
				case HISTORY_ID_LIST:
				{
					int newCommand = ((IGUIListBox*)event.GUIEvent.Caller)->getSelected();
					if (newCommand < editor->m_LastCommand)
					{
						while (newCommand < editor->m_LastCommand)
							editor->Redo();
					}
					else
					{
						while (newCommand > editor->m_LastCommand)
							editor->Undo();
					}
					break;
				}
				case SCENEGRAPH_VISIBLE_ID_LIST:
				{
					if (!g->eventReceiver->IsKeyDown(KEY_SHIFT))
					{
						int sel = ((IGUIListBox*)event.GUIEvent.Caller)->getSelected();
						int id = ((CListBox*)m_SceneGraphPropertiesVisibleList)->getTreeNodeID(sel);
						TreeNode* node = m_sceneGraphTree->FindNode(id);
						if(node)
						{
							m_sceneGraphTree->SetSelected(node);
							void focusCameraOn (ISceneNode*);
							focusCameraOn(node->SceneObject->m_SceneNode);
						}
					}
					break;
				}
			}
			break;

		case EGET_ELEMENT_CLOSED:
			if (event.GUIEvent.Caller == m_ToolsWindow ||
				event.GUIEvent.Caller == m_PropertiesWindow ||
				event.GUIEvent.Caller == m_SceneGraphWindow ||
				event.GUIEvent.Caller == m_HistoryWindow || 
				event.GUIEvent.Caller == m_LevelProperties ||
				event.GUIEvent.Caller == m_PFExporterWindow)
			{								
				event.GUIEvent.Caller->setVisible(false);
				return true;
			}
			if (event.GUIEvent.Caller == g->device->getGUIEnvironment()->getRootGUIElement())
			{
				showSaveWarning();
				return true;
			}

			break;

		case EGET_MENU_ITEM_SELECTED:
			{
				IGUIContextMenu* menu = (IGUIContextMenu*)event.GUIEvent.Caller;
					s32 id = menu->getItemCommandId(menu->getSelectedItem());

				switch(id)
				{
					case MAIN_SCENE_NEW_ITEM:
						//TODO: Ask if modified
						editor->newScene();
						break;

					case MAIN_SCENE_OPEN_ITEM:
						//TODO: Ask if modified
						g->guienv->addFileOpenDialog(L"Load Scene", true, 0, FILE_OPEN_SCENE_DIALOG);
						break;

					case MAIN_SCENE_SAVE_ITEM:
						{
							//TODO: Clear modified flag after succesful save
							trySave();
						}
						break;

					case MAIN_SCENE_SAVE_AS_ITEM:
						{
							//TODO: Clear modified flag after succesful save
							CGUIFileSaveDialog* dialog = new CGUIFileSaveDialog(L"Save Scene As...", g->guienv,
								g->guienv->getRootGUIElement(), FILE_SAVE_SCENE_DIALOG);
							dialog->drop();	
						}
						break;
					case MAIN_SCENE_SAVE_CINEMATICS:
						{
							//m_CinematicCommands
							IWriteFile* f  = g->device->getFileSystem()->createAndWriteFile(CINEMATIC_COMMANDS_FILE);
							
							stringc line = "//autogenerated commands file\n";
							f->write(line.c_str() , line.size());				
							m_CinematicEditor.writeCinematicCommands(f);
							f->drop();
						}
						break;
					case MAIN_SCENE_SET_STR_FILE_ITEM:
						//g->guienv->addFileOpenDialog(L"Set Strings File", true, 0, FILE_SET_STRINGS_FILE_DIALOG);
						break;

					case MAIN_SCENE_SET_MUSIC_FILE_ITEM:
						g->guienv->addFileOpenDialog(L"Set Music File", true, 0, FILE_SET_MUSIC_FILE_DIALOG);
						break;

					case MAIN_VIEW_SWITCH_GRID_ITEM: g->switchGrid(); 
						break;

					case MAIN_VIEW_TOOLS_ITEM: m_ToolsWindow->setVisible(true);
						break;
					case MAIN_VIEW_LEVEL_PROPERTIES : m_LevelProperties->setVisible(true);
						 
					case MAIN_VIEW_PROPERTIES_ITEM: m_PropertiesWindow->setVisible(true);
						break;

					case MAIN_VIEW_SCENEGRAPH_ITEM: m_SceneGraphWindow->setVisible(true);
						break;

					case MAIN_VIEW_HISTORY_ITEM: m_HistoryWindow->setVisible(true);
						break;

					case MAIN_SCENE_PFEXPORT_ITEM:
						createFPExporterWindow();						
						break;

					case MAIN_SCENE_QUIT_ITEM: 
						//as 
						if (editor->IsModified())
						{
							showSaveWarning();
						}
						else
						{
							g->device->closeDevice();
						}
						break;
					case MAIN_SCENE_RECENT_FILE_ITEM:						
						break;
					case MAIN_SCENE_RECENT_FILE_SUB_ITEM:
						{
							int i=0;
							i++;

							int itemOrder = menu->getSelectedItem();
							int fileCount = m_recentFiles.size();
							irr::core::stringw selectItem = m_recentFiles[fileCount - 1 - itemOrder];
							irr::core::stringc fileName = selectItem.c_str();							

							stringc resultDir = g->device->getFileSystem()->getFileDir(fileName) ;
													
							g->device->getFileSystem()->changeWorkingDirectoryTo( resultDir.c_str() );
							m_UserBrowsePath = resultDir;

							editor->writeConfigOptions();

							m_sceneName = fileName;
							s32 loaded = editor->loadScene(fileName);
							if (loaded == 1)
							{								
								g->guienv->addMessageBox(L"Error!", L"Trying to load a newer scene with an older version !!!", true);
							}
						}
						break;
					
					case MAIN_EDIT_UNDO_ITEM:
						editor->Undo();
						break;

					case MAIN_EDIT_REDO_ITEM:
						editor->Redo();
						break;

					case MAIN_EDIT_CLONE_ITEM:
						editor->cloneSelectedNode();
						break;

					case MAIN_EDIT_CLEAR_HISTORY_ITEM:
					{
						int item = menu->getSelectedItem();
						bool checked = menu->isItemChecked(item);
						menu->setItemChecked(item, !checked);
						editor->m_clearHistoryOnNewCommand = !checked;
						break;
					}

					case MAIN_TOOLS_BUILD_ITEM:
					{
						stringc dir = editor->m_editorPath + "\\" + editor->m_buildDataPath;
						editor->saveScene();
						int pos = dir.findLast('\\');
						dir = dir.subString(0, pos);
						ShellExecute(NULL, L"open", stringw((editor->m_editorPath + "\\" + editor->m_buildDataPath).c_str()).c_str(), NULL, stringw(dir.c_str()).c_str(), SW_SHOWNORMAL);
						break;
					}

					case MAIN_TOOLS_LAUNCH_ITEM:
					{
						stringc dir = editor->m_editorPath + "\\" + editor->m_launchEmuPath;
						int pos = dir.findLast('\\');
						dir = dir.subString(0, pos);
						ShellExecute(NULL, L"open", stringw((editor->m_editorPath + "\\" + editor->m_launchEmuPath).c_str()).c_str(),
							stringw((editor->m_SceneFilePath + "\\" + g->device->getFileSystem()->getFileBasename(editor->m_SceneFileName, false)).c_str()).c_str(), stringw(dir.c_str()).c_str(), SW_SHOWNORMAL);

						//ShellExecute(NULL, L"open", stringw((editor->m_editorPath + "\\launch_emu.bat").c_str()).c_str(), 
						//	stringw((editor->m_SceneFilePath + "\\" + editor->m_SceneFileName).c_str()).c_str(), stringw(editor->m_editorPath.c_str()).c_str(), SW_SHOWNORMAL);
						break;
					}

					case MAIN_TOOLS_CLEAN_ITEM:
					{
						stringc dir = editor->m_editorPath + "\\" + editor->m_buildDataPath;
						int pos = dir.findLast('\\');
						dir = dir.subString(0, pos);

						stringw exeCmd = stringw((editor->m_editorPath + "\\" + editor->m_buildDataPath).c_str());
						ShellExecute(NULL, L"open",exeCmd.c_str() , L"clean", stringw(dir.c_str()).c_str(), SW_SHOWNORMAL);
						break;
					}
					case MAIN_TOOLS_SH_COLLISION:
					{
						int item = menu->getSelectedItem();
						bool checked = menu->isItemChecked(item);
						menu->setItemChecked(item, !checked);
						editor->showHideItems("Collisions",!checked);
						break;
					}
					case MAIN_TOOLS_SH_SKYBOX:						
						editor->showHideItems("SkyPlane");
						break;
					case MAIN_TOOLS_SH_NAVMESH:
					{	
						int item = menu->getSelectedItem();
						bool checked = menu->isItemChecked(item);
						menu->setItemChecked(item, !checked);
						editor->showHideItems("NavMesh", !checked);					
						break;
					}
					case MAIN_TOOLS_SH_CAMERAAREA:
					{
						int item = menu->getSelectedItem();
						bool checked = menu->isItemChecked(item);
						menu->setItemChecked(item, !checked);
						editor->showHideItems("CameraArea", !checked);	
						editor->showHideItems("CamCtrlPoint", !checked);
						break;
					}
					case MAIN_TOOLS_SH_TRIGGER:
					{
						int item = menu->getSelectedItem();
						bool checked = menu->isItemChecked(item);
						menu->setItemChecked(item, !checked);
						editor->showHideItems("Trigger", !checked);	
						editor->showHideItems("TriggerSound", !checked);
						editor->showHideItems("TriggerRestore", !checked);
						break;
					}
					case MAIN_HELP_ABOUT_ITEM: 
						showAboutBox();
						break;

					case MAIN_HELP_CONTROLS_ITEM: showControlsHelpBox();
						break;

					case MAIN_VIEW_MAYA_ITEM: g->setActiveCamera(MAYA_CAMERA);
						break;

					case MAIN_VIEW_FPS_ITEM: g->setActiveCamera(FPS_CAMERA);
						break;

				/*	case MAIN_VIEW_WAYPOINT_CAMERA_ITEM:
					{
						CSceneObject* obj;
						int wp = -1;
						for (u32 i = 0; i < editor->m_SceneObjects.size(); i ++)
						{
							if (editor->m_SceneObjects[i]->m_Type == E_WAYPOINT_SCENE_NODE &&
								editor->m_SceneObjects[i]->m_UserData->getAttributeAsInt("$WaypointType") == 0)
							{
								wp = editor->m_SceneObjects[i]->m_SceneNode->getID();
								obj = editor->m_SceneObjects[i];
								break;
							}
						}
						if (wp != -1)
						{
							CWaypointCameraAnimator* anim = (CWaypointCameraAnimator*)*g->camera[WAYPOINT_CAMERA]->getAnimators().begin();
							if (anim->getWaypoint() == -1) anim->setWaypoint(wp);
							g->setActiveCamera(WAYPOINT_CAMERA);
							editor->setSelectedNode(obj->m_SceneNode);
						}
						break;
					}*/

					case MAIN_VIEW_CAMERA_XZ_ITEM:
					case MAIN_VIEW_CAMERA_XY_ITEM:
					case MAIN_VIEW_CAMERA_YZ_ITEM:
					{
						int cameraIndex =
							(id == MAIN_VIEW_CAMERA_XZ_ITEM ? CAMERA_XZ :
							 id == MAIN_VIEW_CAMERA_XY_ITEM ? CAMERA_XY :
															  CAMERA_YZ);
						CPlaneCameraAnimator* anim =
							(CPlaneCameraAnimator*)*g->camera[cameraIndex]->getAnimators().begin();
						ICameraSceneNode* cam = g->sceneManager->getActiveCamera();
						vector3df target = cam->getTarget();
						float distance = (cam->getPosition() - target).getLength();
						g->camera[cameraIndex]->setTarget(target);
						anim->setZoom(distance);
						g->setActiveCamera(cameraIndex);
						break;
					}

					case CONTEXTMENU_ID_NEW_GROUP: 
					{	
						s32 index = editor->getGameObjectIndexFromGameType("Group");
						CSceneObject* obj  = editor->createGameObject( index  ,  -1 );
						//editor->AddInsertCommand(obj);
					}
						break;

					case CONTEXTMENU_ID_ACTIVATE_CAMERA:
						if (editor->hasSelection())
						{
								editor->activateCamera();
						}
						break;
					case CONTEXTMENU_ID_EDIT_CINEMATIC:
					{
						m_CinematicEditor.editCinematic(editor->getSceneObjectFromID(editor->getSelectedNode()->getID()));
						break;
					}
					case CONTEXTMENU_ID_ADJUST_CINEMATIC:
						if( m_CinematicEditor.m_Active == false)
						{
							irr::s32 id = editor->getSelectedNode()->getID();
							CSceneObject *pObject = editor->getSceneObjectFromID(id);
							m_CinematicAdjust.startAdjust(pObject);
						}
						else
						{
							g->guienv->addMessageBox(L"Error!", L"Cinematic editor already opened!");
						}
						break;
					case CONTEXTMENU_ID_DELETE:
						if (editor->hasSelection())
							editor->checkReferentialIntegrity();
						break;

					case CONTEXTMENU_ID_LOCK:
						if (editor->hasSelection())
						{
							array<TreeNode*> Selected = m_sceneGraphTree->GetSelected();
							for (u32 i = 0; i < Selected.size(); i++)
							{
								if(!Selected[i]->Locked)
								{
									Selected[i]->Locked = true;
									setSceneNodeLocked(Selected[i]->ID,true);
								}
							}

							editor->setSelectedNode(0);
						}
						break;
					case CONTEXTMENU_ID_UNLOCK:
						{
							array<s32> removeList;
							removeList.clear();
							for (u32 i = 0; i <((CListBox*)m_SceneGraphPropertiesLockedList)->SelectedList.size(); ++i)
							{									
								int sel = ((CListBox*)m_SceneGraphPropertiesLockedList)->SelectedList[i];
								removeList.push_back(sel);
								int id = ((CListBox*)m_SceneGraphPropertiesLockedList)->getTreeNodeID(sel);
								TreeNode* node = m_sceneGraphTree->FindNode(id);	
								node->Locked = false;
								setSceneNodeLocked(id,false);
							}
							removeList.sort();
							for(int i = removeList.size()-1 ; i>=0;i--)
								((CListBox*)m_SceneGraphPropertiesLockedList)->removeItem(removeList[i]);
							((CListBox*)m_SceneGraphPropertiesLockedList)->setSelected(-1);
						}						
						break;
					case CONTEXTMENU_ID_UNLOCK_VISIBLE_LIST:
						{
							for (u32 i = 0; i <((CListBox*)m_SceneGraphPropertiesLockedList)->SelectedList.size(); ++i)
							{		
								int sel = ((CListBox*)m_SceneGraphPropertiesLockedList)->SelectedList[i];
								int id = ((CListBox*)m_SceneGraphPropertiesLockedList)->getTreeNodeID(sel);
								TreeNode* node = m_sceneGraphTree->FindNode(id);	
								node->Locked = false;
								setSceneNodeLocked(id,false);
							}							
							((CListBox*)m_SceneGraphPropertiesVisibleList)->setSelected(-1);
						}						
						break;

					case CONTEXTMENU_ID_CLONE:
					{
						editor->cloneSelectedNode();
					}
						break;

					case CONTEXTMENU_ID_MOVE_TO_ROOT:
					{
						m_sceneGraphTree->SetSelectedParent(0);
						break;
					}

					case CONTEXTMENU_ID_UP:
					{
						array<TreeNode*> selectNodes = m_sceneGraphTree->GetSelected();
						if( selectNodes.size() >1)
						{
							break;
						}

						m_sceneGraphTree->MovePos(selectNodes[0],true);						
						break;
					}

					case CONTEXTMENU_ID_DOWN:
					{
						array<TreeNode*> selectNodes = m_sceneGraphTree->GetSelected();
						if( selectNodes.size() >1)
						{
							break;
						}

						m_sceneGraphTree->MovePos(selectNodes[0],false);						
						break;
					}

					case CONTEXTMENU_ID_SELECT:
					{
						int id = editor->m_menuIds[menu->getSelectedItem()];
						editor->toggleToSelection(editor->getSceneObjectFromID(id)->m_SceneNode);
						break;
					}

					case CONTEXTMENU_ID_VISIBLE:
					{
						CMultiCommand* multi = new CMultiCommand;
						for (u32 i = 0; i <((CListBox*)m_SceneGraphPropertiesInvisibleList)->SelectedList.size(); ++i)
						{		
							int sel = ((CListBox*)m_SceneGraphPropertiesInvisibleList)->SelectedList[i];
							int id = ((CListBox*)m_SceneGraphPropertiesInvisibleList)->getTreeNodeID(sel);
					
							CSetVisibleCommand* vis = new CSetVisibleCommand(id, true);
							multi->setDescription(vis->getDescription());
							multi->addCommand(vis);
							vis->drop();
						}
						editor->AddCommand(multi);								

						((CListBox*)m_SceneGraphPropertiesInvisibleList)->setSelected(-1);					

						break;
					}
					case CONTEXTMENU_ID_INVISIBLE:
					{
						CMultiCommand* multi = new CMultiCommand;
						for (u32 i = 0; i <((CListBox*)m_SceneGraphPropertiesVisibleList)->SelectedList.size(); ++i)
						{		
							int sel = ((CListBox*)m_SceneGraphPropertiesVisibleList)->SelectedList[i];
							int id = ((CListBox*)m_SceneGraphPropertiesVisibleList)->getTreeNodeID(sel);
							CSetVisibleCommand* vis = new CSetVisibleCommand(id, false);
							multi->setDescription(vis->getDescription());
							multi->addCommand(vis);
							vis->drop();
						}					
						editor->AddCommand(multi);	
						((CListBox*)m_SceneGraphPropertiesVisibleList)->setSelected(-1);

						break;						
					}
					case CINEMATIC_CONTEXT_NEW_OBJ_THREAD:
					case CINEMATIC_CONTEXT_NEW_CAMERA_THREAD:
					case CINEMATIC_CONTEXT_NEW_BASIC_THREAD:
					case CINEMATIC_CONTEXT_EDIT_THREAD:
					case CINEMATIC_CONTEXT_RENAME_THREAD:
					case CINEMATIC_CONTEXT_DELETE_THREAD:
					case CINEMATIC_CONTEXT_CLONE_THREAD:
					case CINEMATIC_CONTEXT_PASTE_THREAD:
					case CINEMATIC_CONTEXT_COPY_CINEMATIC:
					case CINEMATIC_CONTEXT_CUT_CINEMATIC:
					case CINEMATIC_CONTEXT_PASTE_CINEMATIC:
					case CINEMATIC_CONTEXT_COPY_GROUP_CINEMATIC:
					case CINEMATIC_CONTEXT_PASTE_GROUP_CINEMATIC:
					{
						m_CinematicEditor.UpdateCurrentCinematic();
						break;
					}

					case CONTEXTMENU_ID_LINK_TO:
					{
						editor->m_bLinkRoomMode = !editor->m_bLinkRoomMode;
						editor->m_bLinkRoomModeStep = 0;
					}
					break;
				}
			}
			break;

		case EGET_BUTTON_CLICKED:
		{
			s32 id = event.GUIEvent.Caller->getID();
			switch (id)
			{

				//case TOOLS_ID_INSERT_CUBE_BTN:
				//	editor->insertCube(-1);
				//	return true;

				//case TOOLS_ID_INSERT_SPHERE_BTN:
				//	editor->insertSphere(-1);
				//	return true;

				//case TOOLS_ID_INSERT_TERRAIN_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Terrain Map", true, 0, FILE_OPEN_TERRAIN_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_NAVMESH_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Navigation Mesh", true, 0, FILE_OPEN_NAVMESH_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_SKYBOX_BTN:
				//	{
				//		m_SkyBoxTextureIndex = 0;
				//		for (int m = 0; m < 6; m ++)
				//			m_SkyBoxTextures[m] = "";
				//		g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//		g->guienv->addFileOpenDialog(L"Select Top Texture", true, 0, FILE_OPEN_SKYBOX_DIALOG);
				//	}
				//	return true;

				//case TOOLS_ID_INSERT_CAMERA_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Camera", true, 0, FILE_OPEN_CAMERA_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_BILLBOARD_BTN:
				//	editor->insertBillboard(-1);
				//	return true;

				//case TOOLS_ID_INSERT_STATIC_MESH_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Static Mesh", true, 0, FILE_OPEN_STATIC_MESH_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_ANIM_MESH_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Animated Mesh", true, 0, FILE_OPEN_ANIMATED_MESH_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_GEOMETRY_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Geomentry Mesh", true, 0, FILE_OPEN_GEOMETRY_DIALOG);
				//	return true;

				//case TOOLS_ID_INSERT_COLLISIONS_BTN:
				//	g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
				//	g->guienv->addFileOpenDialog(L"Load Collision Mesh", true, 0, FILE_OPEN_COLLISIONS_DIALOG);
				//	return true;

				case TOOLS_ID_SAVE_EFFECTS_BTN:
					editor->saveEffectPreset();
				return true;

				case TOOLS_ID_DELETE_BTN:
					if (editor->hasSelection())
						editor->checkReferentialIntegrity();
					return true;

				case TOOLS_ID_ADD_EFFECT_BTN:
					{
						editor->createEffectNameInput();
					}
					return true;

				case TOOLS_ID_CLONE_EFFECT_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						if (sel != -1)
						{
							editor->createEffectNameInput(true);
						}						
					}
				break;

				case TOOLS_ID_RESTART_EFFECT_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						if (sel != -1)
						{
							for (u32 i=0; i < editor->m_Effects[sel]->m_ParticleSystems.size(); i++)
							{
								editor->m_Effects[sel]->m_ParticleSystems[i]->Restart();
							}
						}
					}
					break;

				case TOOLS_ID_REMOVE_EFFECT_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						if (sel != -1)
						{
							lb->removeItem(sel);
							delete editor->m_Effects[sel];
							editor->m_Effects.erase(sel);
							IGUIListBox* lb_ps = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
							lb_ps->clear();

							for (u32 i=0; i < editor->m_GameLists.size(); i++)
							{
								if (editor->m_GameLists[i].Name == "EffectType")
								{
									editor->m_GameLists[i].Items.erase(sel);
								}
							}
						}
					}
					return true;
				
				case TOOLS_ID_ADD_PS_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						if (sel != -1)
						{
							editor->createPSNameInput();
						}
					}
					return true;

				case TOOLS_ID_REMOVE_PS_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						if (sel != -1)
						{
							IGUIListBox* lb_ps = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
							int sel_ps = lb_ps->getSelected();
							lb_ps->removeItem(sel_ps);
							editor->m_Effects[sel]->m_ParticleSystems[sel_ps]->remove();
							editor->m_Effects[sel]->m_ParticleSystems[sel_ps]->drop();
							editor->m_Effects[sel]->m_ParticleSystems.erase(sel_ps);
							createSelectedPSProperties();
						}
					}
					return true;

				case TOOLS_ID_CLONE_PS_BTN:
				case TOOLS_ID_COPY_PS_BTN:
				case TOOLS_ID_PASTE_PS_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();

						if(id==TOOLS_ID_COPY_PS_BTN)
						{
							m_copyedEffectIndex = sel;
						}

						if (sel != -1)
						{
							IGUIListBox* lb_ps = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
							int sel_ps = lb_ps->getSelected();

							if(id==TOOLS_ID_COPY_PS_BTN)
							{
								m_copyedPsIndex = sel_ps;
							}

							ISceneNode* node = g->sceneManager->getRootSceneNode();

							if(id==TOOLS_ID_CLONE_PS_BTN)
							{
								if (sel_ps != -1)
								{
									ISceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps]->clone();
									pNode->setVisible(true);
									node->addChild(pNode);
									editor->m_Effects[sel]->m_ParticleSystems.push_back((IFpsParticleSystemSceneNode*)pNode);
									lb_ps->addItem( stringw(pNode->getName()).c_str() );
								}
							}
							else if(id==TOOLS_ID_PASTE_PS_BTN)
							{
								if(m_copyedEffectIndex>=0 && m_copyedEffectIndex<editor->m_Effects.size())
								{
									if(m_copyedPsIndex>=0 && m_copyedPsIndex<editor->m_Effects[m_copyedEffectIndex]->m_ParticleSystems.size())
									{
										ISceneNode* pNode = editor->m_Effects[m_copyedEffectIndex]->m_ParticleSystems[m_copyedPsIndex]->clone();
										pNode->setVisible(true);
										node->addChild(pNode);
										editor->m_Effects[sel]->m_ParticleSystems.push_back((IFpsParticleSystemSceneNode*)pNode);
										lb_ps->addItem( stringw(pNode->getName()).c_str() );
									}
								}
							}
						}
					}
					return true;				

				case EFFECT_NAME_ID_OK_BTN:
					{
						IGUIWindow* pEffectNameInputWindow = (IGUIWindow*)g->guienv->getRootGUIElement()->getElementFromId(WND_ID_EFFECT_NAME, true);
						stringw effectName = pEffectNameInputWindow->getElementFromId(EFFECT_NAME_ID_EDIT_NAME_BOX)->getText();
						if (effectName == "")
							return true;

						pEffectNameInputWindow->remove();
						pEffectNameInputWindow = 0;

						CEffect* pEffect = new CEffect(effectName);
						editor->m_Effects.push_back(pEffect);

						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						lb->addItem(effectName.c_str());

						for (u32 i=0; i < editor->m_GameLists.size(); i++)
						{
							if (editor->m_GameLists[i].Name == "EffectType")
							{
								editor->m_GameLists[i].Items.push_back(pEffect->m_effectName);
							}
						}
					}
					return true;

					case EFFECT_NAME_ID_OK_BTN_CLONE:
					{
						IGUIWindow* pEffectNameInputWindow = (IGUIWindow*)g->guienv->getRootGUIElement()->getElementFromId(WND_ID_EFFECT_NAME, true);
						stringw effectName = pEffectNameInputWindow->getElementFromId(EFFECT_NAME_ID_EDIT_NAME_BOX)->getText();
						if (effectName == "")
							return true;

						pEffectNameInputWindow->remove();
						pEffectNameInputWindow = 0;

						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);

						CEffect* pEffect = new CEffect(effectName);

						int sel = lb->getSelected();
						ISceneNode* node = g->sceneManager->getRootSceneNode();
						if (sel != -1)
						{
							for (u32 j=0; j < editor->m_Effects[sel]->m_ParticleSystems.size(); j++)
							{
								ISceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[j]->clone();
								pNode->setVisible(true);
								node->addChild(pNode);
								pEffect->m_ParticleSystems.push_back((IFpsParticleSystemSceneNode*)pNode);
							}

						}

						editor->m_Effects.push_back(pEffect);

						lb->addItem(effectName.c_str());

						for (u32 i=0; i < editor->m_GameLists.size(); i++)
						{
							if (editor->m_GameLists[i].Name == "EffectType")
							{
								editor->m_GameLists[i].Items.push_back(pEffect->m_effectName);
							}
						}		
					}
					return true;

				case PS_NAME_ID_OK_BTN:
					{
						IGUIWindow* pPSNameInputWindow = (IGUIWindow*)g->guienv->getRootGUIElement()->getElementFromId(WND_ID_PS_NAME, true);
						stringw psName = pPSNameInputWindow->getElementFromId(PS_NAME_ID_EDIT_NAME_BOX)->getText();
						if (psName == "")
							return true;

						pPSNameInputWindow->remove();
						pPSNameInputWindow = 0;

						//IFpsParticleSystemSceneNode* pNode = ((CFpsSceneManager*)g->sceneManager)->addFpsParticleSystemSceneNode();
						//pNode->setName(psName.c_str());
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();
						//editor->m_Effects[sel]->m_ParticleSystems.push_back(pNode);
						//pNode->grab();

						lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
						lb->addItem(psName.c_str());
						lb->setSelected(lb->getItemCount() - 1);

						createSelectedPSProperties();
					}
					return true;

				case TOOLS_ID_ADD_AFFECTOR_BTN:
					{
						IGUIComboBox* pCombo = (IGUIComboBox*)m_PSAffectorTab->getElementFromId(TOOLS_ID_AFFECTORS_COMBO);
						IGUIListBox* pList = (IGUIListBox*)m_PSAffectorTab->getElementFromId(TOOLS_ID_AFFECTORS_LIST);
						
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
						int sel = lb->getSelected();

						if (sel == -1) return true;
						
						lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
						int sel_ps = lb->getSelected();

						if (sel_ps == -1) return true;

						IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];

						switch (pCombo->getSelected())
						{
						case 0:
							{
								IFpsParticleAttractionAffector* pAffector = pNode->createAttractionAffector(vector3df());
								pNode->addAffector(pAffector);
								pList->addItem(L"Attraction");
							}
							break;

						case 1:
							{
								IFpsParticleFadeOutAffector* pAffector = pNode->createFadeOutParticleAffector();
								pNode->addAffector(pAffector);
								pList->addItem(L"FadeOut");
							}
							break;

						case 2:
							{
								IFpsParticleGravityAffector* pAffector = pNode->createGravityAffector();
								pNode->addAffector(pAffector);
								pList->addItem(L"Gravity");
							}
							break;

						case 3:
							{
								IFpsParticleRotationAffector* pAffector = pNode->createRotationAffector();
								pNode->addAffector(pAffector);
								pList->addItem(L"Rotation");
							}
							break;

						case 4:
							{
								IFpsParticleSizeAffector* pAffector = pNode->createSizeAffector();
								pNode->addAffector(pAffector);
								pList->addItem(L"Scale");
							}
							break;

						case 5:
							{
								IFpsParticleSpinAffector* pAffector = pNode->createSpinAffector();
								pNode->addAffector(pAffector);
								pList->addItem(L"Spin");
							}
							break;
						}

						pList->setSelected(pList->getItemCount() - 1);
						createSelectedAffectorProperties();
					}
					return true;

				case TOOLS_ID_REMOVE_AFFECTOR_BTN:
					{
						IGUIListBox* pList = (IGUIListBox*)m_PSAffectorTab->getElementFromId(TOOLS_ID_AFFECTORS_LIST);
						int selAff = pList->getSelected();
						
						if (selAff != -1)
						{
							IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
							int sel = lb->getSelected();

							if (sel == -1) return true;
							
							lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);
							int sel_ps = lb->getSelected();

							if (sel_ps == -1) return true;

							IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];

							list<IFpsParticleAffector*> _affectors = pNode->getAffectors();
							int currIndex = 0;
							for(list<IFpsParticleAffector*>::Iterator it = _affectors.begin(); it != _affectors.end(); it++)
							{
								if (currIndex == selAff)
								{
									pNode->removeAffector((*it));
									break;
								}

								currIndex++;
							}

							pList->removeItem(selAff);
							createSelectedAffectorProperties();
						}
					}
					return true;

				case TOOLS_ID_SNAP2COL_BTN:
				{
					if (editor->hasSelection())
					{
						editor->snapNode();
						updateProperties();
					}
					else
					{
						g->guienv->addMessageBox(L"Error!", L"Select object first!", true);
					}
					return true;
				}
				case TOOLS_ID_INSERT_GAME_OBJECT:
					{
						//editor->setSelectedNode(0);

						IGUIListBox* listBox = (IGUIListBox*)m_ToolsObjectsTab->getElementFromId(TOOLS_ID_PICKLIST);
						if (listBox->getSelected() < 0)
						{
							g->guienv->addMessageBox(L"Error!", L"Select object from list first!", true);
						}
						else
						{
							//editor->m_pInsertObjTemplate = editor->m_GameObjects[listBox->getSelected()];
							int index = -1;
							int count = m_allGameObject.size();

							irr::core::stringw selectedText = listBox->getListItem( listBox->getSelected() );
							for(int i=0;i<count;i++)
							{
								if( selectedText == m_allGameObject[i] )
								{
									index = i;
									break;
								}
							}
							assert( index>=0 );
							editor->m_pInsertObjTemplate = editor->m_GameObjects[index];
							editor->preprocessCreateCameraArea(editor->m_pInsertObjTemplate);
							editor->m_bPositionObjOnInsert = true;
						}
					}
					return true;

				case TOOLS_ID_MOVE_BTN:
				case TOOLS_ID_MOVE_LOCAL_BTN:
				case TOOLS_ID_ROTATE_BTN:
				case TOOLS_ID_ROTATE_LOCAL_BTN:
				case TOOLS_ID_SCALE_BTN:
				case TOOLS_ID_MODIFY_TRIG_BTN:
					m_MovePushButton->setPressed(id == TOOLS_ID_MOVE_BTN  && m_MovePushButton->isPressed());
					m_MoveLocalPushButton->setPressed(id == TOOLS_ID_MOVE_LOCAL_BTN && m_MoveLocalPushButton->isPressed());
					m_RotatePushButton->setPressed(id == TOOLS_ID_ROTATE_BTN && m_RotatePushButton->isPressed());
					m_RotateLocalPushButton->setPressed(id == TOOLS_ID_ROTATE_LOCAL_BTN && m_RotateLocalPushButton->isPressed());
					m_ScalePushButton->setPressed(id == TOOLS_ID_SCALE_BTN && m_ScalePushButton->isPressed());
					m_ModifyPushButton->setPressed(id == TOOLS_ID_MODIFY_TRIG_BTN && m_ModifyPushButton->isPressed());
					editor->updateControls();
					return true;

				case TOOLS_ID_CORRECT_CAMAREA_BTN:
					editor->CorrectSelectedCameraArea();					
					return true;

				case TOOLS_ID_SET_CAMAREA_BTN:
					editor->OnOffCameraModeCtrlPoint(m_SetCameraButton->isPressed());
					return true;

				case TOOLS_ID_COPY_CAMERA_BTN:
					editor->CopySelectedCameraPoint();
					return true;

				case PROP_FILE_BTN:
					return propertyButtonPressed(event);
			
				case PROP_LINK_BTN:
					{
						IGUIButton* buttonLink = (IGUIButton*)event.GUIEvent.Caller;
						if (buttonLink->isPressed())
						{
							m_linkChangedProp = NULL;

							for (u32 i = 0; i < m_Properties.size(); i ++)	
								if (m_Properties[i].m_GUIElementButton == buttonLink)
								{
									m_linkChangedProp = &m_Properties[i];
									break;
								}

							//m_SceneGraphWindow->setVisible(false);
							//m_ToolsWindow->setVisible(false);
						}
						else
						{
							m_linkChangedProp = NULL;
							//m_SceneGraphWindow->setVisible(true);
							//m_ToolsWindow->setVisible(true);
						}
					}
					break;

				case PROP_PLAY_BTN:
					{
						CSceneObject* pObj = editor->getSceneObjectFromID(editor->getSelectedNode()->getID());
//						pObj->RestartCurrentAnim();
					}
					break;

				case PROP_EDIT_CINEMATIC_BTN:
				{
					m_CinematicEditor.editCinematic(editor->getSceneObjectFromID(editor->getSelectedNode()->getID()));
				
					break;
				}

				case PROP_EDIT_OFFSET_BTN:
					{
						IGUIButton* button = (IGUIButton*)event.GUIEvent.Caller;
						CSceneObject* pObj = editor->getSceneObjectFromID(editor->getSelectedNode()->getID());

						if (button->isPressed())
						{
							editor->OnOffCamCtrlPointSetOffset(true, pObj);
						}
						else
						{
							editor->OnOffCamCtrlPointSetOffset(false, pObj);
						}
					}				
					break;

				case PROP_SNAP_TARGET_TO_EDGE_BTN:
					{
						IGUIButton* button = (IGUIButton*)event.GUIEvent.Caller;
						CSceneObject* pObj = editor->getSceneObjectFromID(editor->getSelectedNode()->getID());
						editor->SnapCamCtrlPointTargetToEdge(pObj);
					}
					break;

				case PROP_EDIT_MOVE_TO_CAM:
					{
						IGUIButton* button = (IGUIButton*)event.GUIEvent.Caller;
						int obj_id = editor->getSelectedNode()->getID();
						CSceneObject* pObj = editor->getSceneObjectFromID(obj_id);
												
						int init_cam_id = pObj->m_UserData->getAttributeAsInt("^Init^CameraArea");
						if(init_cam_id>=0)
						{
							CSceneObject* camObj = editor->getSceneObjectFromID(init_cam_id);
							if(camObj!=0)
							{
								irr::core::vector3df oldPos = pObj->m_SceneNode->getPosition();
								irr::core::vector3df newPos = camObj->m_SceneNode->getAbsolutePosition();
								pObj->m_SceneNode->setPosition(newPos);//for spiderman, always on root
								editor->AddCommand(new CMoveCommand(obj_id, oldPos, newPos));
							}
						}												
					}
					break;

				case PROP_EDIT_CINEMATIC_WO:
				case PROP_EDIT_CINEMATIC_WI:
				case PROP_EDIT_CINEMATIC_IO:
				case PROP_EDIT_CINEMATIC_OI:
				case PROP_EDIT_CINEMATIC_SP:
				case PROP_EDIT_CINEMATIC_DE:
				{
					CSceneObject* obj = editor->getSceneObjectFromID( editor->getSelectedNode()->getID() );
					
					if (obj)
					{
						int cinematicID = -1;

						if (obj->m_UserData->getAttributeAsString("!GameType") == stringc("Trigger"))
						{								

							if ( id == PROP_EDIT_CINEMATIC_WO ) 
							{
								cinematicID = obj->m_UserData->getAttributeAsInt("^WhileOut^Cinematic");
							}
							else if (id == PROP_EDIT_CINEMATIC_WI)
							{
								cinematicID = obj->m_UserData->getAttributeAsInt("^WhileIn^Cinematic");
							}
							else if (id == PROP_EDIT_CINEMATIC_IO)
							{
								cinematicID = obj->m_UserData->getAttributeAsInt("^InToOut^Cinematic");
							}
							else if (id == PROP_EDIT_CINEMATIC_OI)
							{
								cinematicID = obj->m_UserData->getAttributeAsInt("^OutToIn^Cinematic");
							}
						}
						else if (obj->m_UserData->getAttributeAsString("!GameType") == stringc("SpawnPoint"))
						{
							if (id == PROP_EDIT_CINEMATIC_SP)
							{
								cinematicID = obj->m_UserData->getAttributeAsInt("^Start^Cinematic");
							}
						}
						else if (id == PROP_EDIT_CINEMATIC_DE)
						{
							cinematicID = obj->m_UserData->getAttributeAsInt("^Dead^Cinematic");
						}

						if (cinematicID != -1)	
						{
							CSceneObject* pObj = editor->getSceneObjectFromID(cinematicID);
							if (pObj)
							{
								m_CinematicEditor.editCinematic(pObj);
							}
						}					  
					}

					break;
				}
				case PROP_APPLY_FOG_BTN:
					{
						CSceneObject* pObj = editor->getSceneObjectFromID(editor->getSelectedNode()->getID());
						SColor fogColor = pObj->m_UserData->getAttributeAsColor("FogColor");
						bool bLinearFog = pObj->m_UserData->getAttributeAsBool("LinearFog");
						f32 fogStart = pObj->m_UserData->getAttributeAsFloat("Start");
						f32 fogEnd = pObj->m_UserData->getAttributeAsFloat("End");
						f32 fogDensity = pObj->m_UserData->getAttributeAsFloat("Density");
						bool bPixelFog = pObj->m_UserData->getAttributeAsBool("PixelFog");
						bool bRangeFog = pObj->m_UserData->getAttributeAsBool("RangeFog");

						//g->driver->setFog(fogColor, bLinearFog, fogStart, fogEnd, fogDensity, bPixelFog, bRangeFog);
						g->driver->setFog(fogColor, EFT_FOG_LINEAR, fogStart, fogEnd, fogDensity, bPixelFog, bRangeFog);						
					}
					break;

				case PROP_RESTART_EFFECT_BTN:
					{
						CSceneObject* pObj = editor->getSceneObjectFromID(editor->getSelectedNode()->getID());
						list<ISceneNode*>::ConstIterator it = pObj->m_SceneNode->getChildren().begin();
						for (; it != pObj->m_SceneNode->getChildren().end();it++)
						{
							IFpsParticleSystemSceneNode* pParticleSys = (IFpsParticleSystemSceneNode*)(*it);
							pParticleSys->Restart();
						}
					}
					break;
				case SCENEGRAPH_ID_UP:
					{
						array<TreeNode*> selectNodes = m_sceneGraphTree->GetSelected();
						if( selectNodes.size() >1 || selectNodes.size()==0 )
						{
							break;
						}

						m_sceneGraphTree->MovePos(selectNodes[0],true);
					}
					break;
				case SCENEGRAPH_ID_DOWN:
					{
						array<TreeNode*> selectNodes = m_sceneGraphTree->GetSelected();
						if( selectNodes.size() >1 || selectNodes.size()==0 )
						{
							break;
						}

						m_sceneGraphTree->MovePos(selectNodes[0],false);
					}
					break;
				case SCENEGRAPH_ID_TOP:
					{
						array<TreeNode*> selectNodes = m_sceneGraphTree->GetSelected();
						if( selectNodes.size() >1 || selectNodes.size()==0 )
						{
							break;
						}

						m_sceneGraphTree->MovePos(selectNodes[0],false, true);
					}
					break;
				case VISBLE_LIST_ID_SORT_BTN:
					{
						((CListBox*)m_SceneGraphPropertiesVisibleList)->Sort(true);
					}
					break;

				case TOOLS_ID_ADD_TEMPLATE_BTN:
					{
						editor->createTemplateNameInput();
					}
					break;

				case TEMPLATE_NAME_ID_OK_BTN:
					{
						IGUIWindow* pTemplateNameInputWindow = (IGUIWindow*)g->guienv->getRootGUIElement()->getElementFromId(WND_ID_TEMPLATE_NAME, true);
						stringw templateName = pTemplateNameInputWindow->getElementFromId(TEMPLATE_NAME_ID_EDIT_NAME_BOX)->getText();
						if (templateName == "")
							return true;

						pTemplateNameInputWindow->remove();
						pTemplateNameInputWindow = 0;

						IGUIComboBox* cb = (IGUIComboBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATES_NEW_COMBO, true);
						CGameObject *pObj = editor->m_GameObjects[cb->getSelected()];
						CGameObject *pTemplate = new CGameObject();
						editor->copyAttributes(pTemplate->m_Attributes , pObj->m_Attributes);
						pTemplate->m_Attributes->setAttribute("Name", templateName.c_str());
						editor->m_GameTemplates.push_back(pTemplate);
						
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
						lb->addItem(pTemplate->m_Attributes->getAttributeAsStringW("Name").c_str());

						createSelectedTemplateProperties();
					}
					break;

				case TOOLS_ID_SAVE_TEMPLATE_BTN:
					{
						editor->saveGameTemplates();
					}
					break;

				case TOOLS_ID_INSERT_GAME_TEMPLATE:
					{
						//editor->setSelectedNode(0);

						IGUIListBox* listBox = (IGUIListBox*)m_ToolsTemplatesTab->getElementFromId(TOOLS_ID_TEMPLATE_LIST);
						if (listBox->getSelected() < 0)
						{
							g->guienv->addMessageBox(L"Error!", L"Select object from list first!", true);
						}
						else
						{
							editor->m_pInsertObjTemplate = editor->m_GameTemplates[listBox->getSelected()];
							editor->m_bPositionObjOnInsert = true;
						}
					}
					return true;

				case TOOLS_ID_DELETE_TEMPLATE_BTN:
					{
						IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
						int sel = lb->getSelected();

						if (sel != -1)
						{
							lb->removeItem(sel);
							editor->m_GameTemplates.erase(sel);
							createSelectedTemplateProperties();
						}
					}
					break;				

			}

			if(id>=PFEXPORT_BT_EXPORT && id<=PFEXPORT_CHECKBOX_RESERVED)
			{
				//for export illumination maps
				FPExportWinButtonPressed(event);
			}
			break;
		}

		case EGET_FILE_CHOOSE_DIALOG_CANCELLED:
			m_bUseEditorRelativePath = false;
			break;

		case EGET_FILE_SELECTED:
			{
				IGUIFileOpenDialog* dialog = (IGUIFileOpenDialog*)event.GUIEvent.Caller;					
				
				m_UserBrowsePath = g->device->getFileSystem()->getFileDir(dialog->getFileName());

				stringc fileName;
				if (m_bUseEditorRelativePath)
				{
					fileName = g->getRelativePath(editor->m_editorPath, dialog->getFileName());
					m_bUseEditorRelativePath = false;
				}
				else
				{
					fileName = g->getRelativePath(editor->m_SceneFilePath, dialog->getFileName());
				}

				g->device->getFileSystem()->changeWorkingDirectoryTo(editor->m_SceneFilePath.c_str());
				
				//fix for iPhone
				fileName.replace('/','\\');

				switch(event.GUIEvent.Caller->getID())
				{
					//case FILE_OPEN_STATIC_MESH_DIALOG:
					//	editor->insertStaticMesh(fileName , -1);
					//	return true;

					//case FILE_OPEN_SKYBOX_DIALOG:
					//	m_SkyBoxTextures[m_SkyBoxTextureIndex] = fileName;
					//	m_SkyBoxTextureIndex ++;
					//	if (m_SkyBoxTextureIndex < 6)
					//	{
					//		stringw caption;
					//		switch (m_SkyBoxTextureIndex)
					//		{
					//			case 1:	caption = "Select Bottom Texture"; break;
					//			case 2: caption = "Select Left Texture"; break;
					//			case 3: caption = "Select Right Texture"; break;
					//			case 4: caption = "Select Front Texture"; break;
					//			case 5: caption = "Select Back Texture"; break;
					//		}
					//		g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
					//		g->guienv->addFileOpenDialog(caption.c_str(), true, 0, FILE_OPEN_SKYBOX_DIALOG);
					//	}
					//	else
					//		editor->insertSkybox(m_SkyBoxTextures , -1);
					//	return true;
			
					//case FILE_OPEN_TERRAIN_DIALOG:
					//	editor->insertTerrain(fileName , -1);
					//	return true;

					//case FILE_OPEN_NAVMESH_DIALOG:
					//	editor->insertNavMesh(fileName , -1);
					//	return true;
					
					//case FILE_OPEN_CAMERA_DIALOG:
					//	editor->insertCamera(fileName , -1);
					//	return true;
					
				//	case FILE_OPEN_ANIMATED_MESH_DIALOG:
				//		editor->insertAnimatedMesh(fileName , -1);
				//		return true;

					case FILE_OPEN_SCENE_DIALOG:
					{							
						stringc result = g->device->getFileSystem()->getFileDir(dialog->getFileName()) ;
						
						g->device->getFileSystem()->changeWorkingDirectoryTo( result.c_str() );						

						editor->writeConfigOptions();
						m_sceneName = dialog->getFileName();

						irr::core::stringw newFileName = m_sceneName.c_str();
						if( m_recentFiles.linear_search( newFileName ) == -1)
						{
							m_recentFiles.push_back(newFileName);
							saveRecentFiles();
						}

						if(g->device->getFileSystem()->existFile((m_sceneName+".autosave").c_str()))
						{
							showAutosaveWarning();
							return true;
						}
						s32 loaded = editor->loadScene(m_sceneName);
						if (loaded == 1)
						{								
							g->guienv->addMessageBox(L"Error!", L"Trying to load a newer scene with an older version !!!", true);
						}

						return true;
					}
					case FILE_SAVE_SCENE_DIALOG:
						{
							g->device->getFileSystem()->changeWorkingDirectoryTo(
								g->device->getFileSystem()->getFileDir(dialog->getFileName()).c_str() );
							editor->setSceneFileName(dialog->getFileName());
							
							saveRecentFiles();

							editor->writeConfigOptions();

							editor->saveScene();

							editor->saveEffectPreset();

							if ( m_bQuitAfterSave )
							{
								g->device->closeDevice();
							}
						}
						return true;
					case FILE_PROP_FILE_OPEN_DIALOG:
						{
							m_FileOpenProp->m_GUIElementEdit->setText(stringw(fileName.c_str()).c_str());
							SEvent evt;
							evt.GUIEvent.Caller = m_FileOpenProp->m_GUIElementEdit;
							return propertyEditBoxEnter(evt);							
						}

					case FILE_SET_STRINGS_FILE_DIALOG:
						{
							//editor->m_stringsFile = g->getRelativePath(editor->m_SceneFilePath, dialog->getFileName());
							//SGameList list;

							//if (!editor->LoadListFromFile(editor->m_stringsFile, list))
							//{
							//	g->guienv->addMessageBox(L"Error!", (stringw(L"Cannot load strings '") + stringw(editor->m_stringsFile.c_str()).c_str() + stringw(L"'!")).c_str(), true);
							//}
							//else
							//{
							//	editor->m_GameLists.push_back(list);
							//	if( editor->m_stringsFile.find("main.xml")!=-1)
							//	{
							//		editor->m_stringsList = editor->m_GameLists.getLast();
							//	}
							//}

							return true;
						}

					case FILE_SET_MUSIC_FILE_DIALOG:
						{
							editor->m_musicFile = g->getRelativePath(editor->m_SceneFilePath, dialog->getFileName());
							return true;
						}					

					//case FILE_OPEN_GEOMETRY_DIALOG:
					//	editor->insertRoom(fileName , -1);
					//	return true;

					//case FILE_OPEN_COLLISIONS_DIALOG:
					//	editor->insertCollisions(fileName , -1);
					//	return true;
				}
			}			
			break;
		
		case EGET_ELEMENT_FOCUS_LOST:	
		{
			int type = event.GUIEvent.EventType;			
			IGUIEditBox* e = (IGUIEditBox*) (event.GUIEvent.Caller);
			if (e)
			{
				propertyEditBoxEnter(event);	
			}
			return false;
		}
		case EGET_EDITBOX_ENTER:
			return propertyEditBoxEnter(event);					

		case EGET_COMBO_BOX_CHANGED:
			return propertyComboBoxChanged(event);

		case EGET_CHECKBOX_CHANGED:
		{
			s32 id = event.GUIEvent.Caller->getID();
			if(id>=PFEXPORT_BT_EXPORT && id<=PFEXPORT_CHECKBOX_RESERVED)
				FPExportWinCheckBoxChanged(event);
			else
				return propertyCheckBoxChanged(event);
		}

		case EGET_MESSAGEBOX_YES:
		{
			if (event.GUIEvent.Caller->getID() == MSG_BOX_SAVE_SCENE)
			{
				m_bQuitAfterSave = true; 
				trySave();					
				//g->device->closeDevice();
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_CONFIRM_DELETE)
			{
				editor->removeReferences();
				editor->deleteSelectedNode();
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_AUTOSAVE_SCENE)
			{
				//RC TO DO						
				g->device->getFileSystem()->changeWorkingDirectoryTo( m_UserBrowsePath.c_str() );
				s32 loaded = editor->loadScene((m_sceneName+".autosave"));
				if (loaded == 1)
				{								
					g->guienv->addMessageBox(L"Error!", L"Trying to load a newer scene with an older version !!!", true);
				}					
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_CONFIRM_COPY_CAMERA)
			{
				editor->CopySelectedCameraPoint(true);
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_SAVE_CINEMATIC)
			{
				if( m_CinematicEditor.m_Active )
				{
					m_CinematicEditor.closeCinematic(true);
				}
			}
		}
		break;
		case EGET_MESSAGEBOX_NO:
		{
			if (event.GUIEvent.Caller->getID() == MSG_BOX_SAVE_SCENE)
			{
				editor->DeleteAutoSave();
				g->device->closeDevice();
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_AUTOSAVE_SCENE)
			{
				g->device->getFileSystem()->changeWorkingDirectoryTo( m_UserBrowsePath.c_str() );
				s32 loaded = editor->loadScene((m_sceneName));
				if (loaded == 1)
				{								
					g->guienv->addMessageBox(L"Error!", L"Trying to load a newer scene with an older version !!!", true);
				}		
			}

			if (event.GUIEvent.Caller->getID() == MSG_BOX_SAVE_CINEMATIC)
			{
				if( m_CinematicEditor.m_Active )
				{
					m_CinematicEditor.closeCinematic(false);
				}
			}
		}
		break;

		case EGET_TABLE_CHANGED:
		case EGET_TABLE_SELECTED_AGAIN:
		{
			if (event.GUIEvent.Caller == m_LevelProperties)
			{
				return true;
			}
		}
		break;
	}

	
	return false;
}

void CUserInterface::createMainMenu()
{	
	IGUIContextMenu* menu = g->guienv->addMenu();
	
	menu->addItem(L"File", -1, true, true);
	menu->addItem(L"View", -1, true, true);
	menu->addItem(L"Edit", -1, true, true);
	menu->addItem(L"Tools", -1, true, true);
	menu->addItem(L"Help", -1, true, true);

	IGUIContextMenu* submenu;
	
	submenu = menu->getSubMenu(0);
	submenu->addItem(L"New", MAIN_SCENE_NEW_ITEM);
	submenu->addItem(L"Open", MAIN_SCENE_OPEN_ITEM);
	submenu->addItem(L"Save", MAIN_SCENE_SAVE_ITEM);
	submenu->addItem(L"Save As...", MAIN_SCENE_SAVE_AS_ITEM);
	submenu->addItem(L"Export Cinematics Headers", MAIN_SCENE_SAVE_CINEMATICS);
	submenu->addSeparator();
	//submenu->addItem(L"Set Strings File", MAIN_SCENE_SET_STR_FILE_ITEM);
	submenu->addItem(L"Set Music File", MAIN_SCENE_SET_MUSIC_FILE_ITEM);
	submenu->addItem(L"Exporte Illumination Maps", MAIN_SCENE_PFEXPORT_ITEM);
	submenu->addSeparator();
	submenu->addItem(L"Quit", MAIN_SCENE_QUIT_ITEM);	
	
	if( m_recentFiles.size()>0 )
	{
		submenu->addSeparator();
		irr::u32 val = submenu->addItem(L"Recent File", MAIN_SCENE_RECENT_FILE_ITEM,true, true);

		IGUIContextMenu* recentMenu = submenu->getSubMenu(val);
		int count = m_recentFiles.size();
		for(int i= count -1;i>=0;i--)
		{
			recentMenu->addItem(m_recentFiles[i].c_str() , MAIN_SCENE_RECENT_FILE_SUB_ITEM);
		}
	}

	submenu = menu->getSubMenu(1);
    submenu->addItem(L"Tools", MAIN_VIEW_TOOLS_ITEM);
    submenu->addItem(L"Properties", MAIN_VIEW_PROPERTIES_ITEM);
	submenu->addItem(L"Scene Graph", MAIN_VIEW_SCENEGRAPH_ITEM);
	submenu->addItem(L"History", MAIN_VIEW_HISTORY_ITEM);
	submenu->addItem(L"Level Properties", MAIN_VIEW_LEVEL_PROPERTIES);
    submenu->addSeparator();
	submenu->addItem(L"Maya Style Camera    Ctrl+1", MAIN_VIEW_MAYA_ITEM);
	submenu->addItem(L"Top View Camera       Ctrl+2", MAIN_VIEW_CAMERA_XY_ITEM);
	submenu->addItem(L"First Person Camera Ctrl+3", MAIN_VIEW_FPS_ITEM);
	//submenu->addItem(L"Level Waypoint Path Camera", MAIN_VIEW_WAYPOINT_CAMERA_ITEM);
	//submenu->addItem(L"XZ Camera", MAIN_VIEW_CAMERA_XZ_ITEM);
	//submenu->addItem(L"YZ Camera", MAIN_VIEW_CAMERA_YZ_ITEM);
	submenu->addSeparator();
	submenu->addItem(L"Switch Grid", MAIN_VIEW_SWITCH_GRID_ITEM);

	submenu = menu->getSubMenu(2);
	submenu->addItem(L"Undo      Ctrl+Z", MAIN_EDIT_UNDO_ITEM);
	submenu->addItem(L"Redo      Ctrl+Y", MAIN_EDIT_REDO_ITEM);
	submenu->addItem(L"Clone", MAIN_EDIT_CLONE_ITEM);
	submenu->addItem(L"Clear history on new command", MAIN_EDIT_CLEAR_HISTORY_ITEM, true, false, true);

	submenu = menu->getSubMenu(3);
	submenu->addItem(L"Build Data", MAIN_TOOLS_BUILD_ITEM);
	submenu->addItem(L"Launch Emulator", MAIN_TOOLS_LAUNCH_ITEM);
	submenu->addSeparator();
	submenu->addItem(L"Clean Data", MAIN_TOOLS_CLEAN_ITEM);
	
	submenu->addSeparator();
	int _item = submenu->addItem(L"Show/Hide Colissions", MAIN_TOOLS_SH_COLLISION);
	submenu->setItemChecked(_item,true);
	submenu->addItem(L"Show/Hide SkyBoxes", MAIN_TOOLS_SH_SKYBOX); 
	_item = submenu->addItem(L"Show/Hide NavMeshes", MAIN_TOOLS_SH_NAVMESH); 
	submenu->setItemChecked(_item,true);

	_item = submenu->addItem(L"Show/Hide Camera Areas", MAIN_TOOLS_SH_CAMERAAREA); 
	submenu->setItemChecked(_item,true);

	_item = submenu->addItem(L"Show/Hide Trigger", MAIN_TOOLS_SH_TRIGGER); 
	submenu->setItemChecked(_item,true);
	

	submenu = menu->getSubMenu(4);
	submenu->addItem(L"Controls", MAIN_HELP_CONTROLS_ITEM);
	submenu->addItem(L"About", MAIN_HELP_ABOUT_ITEM);
}

void CUserInterface::populateGameObjectList()
{
	stringw itemName;

	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PICKLIST, true);
	
	if (!lb)
		return;

	for (u32 i = 0; i < editor->m_GameObjects.size(); i ++)
	{
		itemName = editor->m_GameObjects[i]->m_Attributes->getAttributeAsStringW("!GameType");
		m_allGameObject.push_back( itemName );
		lb->addItem(itemName.c_str());
	}
}

void CUserInterface::populateEffectsList()
{
	stringw itemName;

	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
	
	if (!lb)
		return;

	for (u32 i = 0; i < editor->m_Effects.size(); i ++)
	{
		itemName = stringw(editor->m_Effects[i]->m_effectName);
		lb->addItem(itemName.c_str());
	}
}

void CUserInterface::populateTemplatesCombo()
{
	stringw itemName;

	IGUIComboBox* cb = (IGUIComboBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATES_NEW_COMBO, true);
	
	if (!cb)
		return;

	for (u32 i = 0; i < editor->m_GameObjects.size(); i ++)
	{
		itemName = editor->m_GameObjects[i]->m_Attributes->getAttributeAsStringW("!GameType");

		cb->addItem(itemName.c_str());
	}
}

void CUserInterface::populateTemplatesList()
{
	stringw itemName;

	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
	
	if (!lb)
		return;

	for (u32 i = 0; i < editor->m_GameTemplates.size(); i ++)
	{
		itemName = editor->m_GameTemplates[i]->m_Attributes->getAttributeAsStringW("Name");

		lb->addItem(itemName.c_str());
	}
}

int CUserInterface::getEditAction()
{
	int result = UI_EDIT_ACTION_NONE;

	if (m_MovePushButton->isPressed())
		result = UI_EDIT_ACTION_MOVE;

	if (m_MoveLocalPushButton->isPressed())
		result = UI_EDIT_ACTION_MOVE_LOCAL;

	if (m_RotatePushButton->isPressed())
		result = UI_EDIT_ACTION_ROTATE;

	if (m_RotateLocalPushButton->isPressed())
		result = UI_EDIT_ACTION_ROTATE_LOCAL;

	if (m_ScalePushButton->isPressed())
		result = UI_EDIT_ACTION_SCALE;

	if (m_ModifyPushButton->isPressed())
		result = UI_EDIT_ACTION_MODIFY;
	
	return result;
}

int CUserInterface::createProperty(CSceneObject* sceneObject, stringw name, int type, s32 x, s32 y, bool bUserData, IGUIElement* parent)
{
	int height = 0;
	int propWidth = 190;
	IGUIElement* edit = 0;
	IGUIElement* button = 0;
	IGUIElement* staticText = 0;
	bool fileDialog = false;
	stringw label;
	bool bReadOnly = false;

	if (((name == L"Mesh") || (name.find(L"Texture") >= 0) || (name.find(L"File") >= 0)) && 
		name.c_str()[0] != L'!')
	{
		fileDialog = true;
	}

	if (fileDialog)
	{
		propWidth = 170;	//20 pixels for file dialog btn
		button = g->guienv->addButton(rect<s32>(x + 170, y + 15, x + 190, y + 35), parent, PROP_FILE_BTN, L"...");
	}
	
	if (name.c_str()[0] == L'^')
	{
		int off = 0;
		int prop = 0;
		if (name.find(L"Cinematic") >= 0)
		{
			if (name.find(L"WhileOut") >= 0 )
			{
				prop = PROP_EDIT_CINEMATIC_WO;
			}
			else if (name.find(L"WhileIn") >= 0 )
			{
				prop = PROP_EDIT_CINEMATIC_WI;
			}
			else if (name.find(L"InToOut") >= 0 )
			{
				prop = PROP_EDIT_CINEMATIC_IO;
			}
			else if (name.find(L"OutToIn") >= 0 )
			{
				prop = PROP_EDIT_CINEMATIC_OI;
			}
			else if (name.find(L"Start") >=0 )
			{
				prop = PROP_EDIT_CINEMATIC_SP;
			}
			else if (name.find(L"Dead") >=0 )
			{
				prop = PROP_EDIT_CINEMATIC_DE;
			}
			else if (name.find(L"Intera") >=0 )
			{
				prop = PROP_EDIT_CINEMATIC_IT;
			}
			else 
			{
				GX_ASSERT( false && "Unknown trigger type !!");
			}
			IGUIElement* b = g->guienv->addButton(rect<s32>(x + 160, y + 15, x + 190, y + 35), parent, prop , L"Edit");
		   //((IGUIButton*)b)->setIsPushButton(true);		
		   off = -30;
		}

		propWidth = 160 + off;	//20 pixels for file dialog btn
		button = g->guienv->addButton(rect<s32>(x + 160 + off, y + 15, x + 190 + off, y + 35), parent, PROP_LINK_BTN, L"Link");
		((IGUIButton*)button)->setIsPushButton(true);		
	}

	if (name.c_str()[0] == L'!')
	{
		label = name.subString(1, name.size() - 1);
		bReadOnly = true;
	}
	else
		label = name;
	
	if (type == EAT_UNKNOWN && label == L"Edit Cinematic")
	{
		propWidth = 190;	
		button = g->guienv->addButton(rect<s32>(x, y, x + 190, y + 20), parent, PROP_EDIT_CINEMATIC_BTN, name.c_str());
		height = 20;
	}

	if (type == EAT_UNKNOWN && label == L"Edit Offset")
	{
		propWidth = 90;	
		button = g->guienv->addButton(rect<s32>(x, y, x + 90, y + 20), parent, PROP_EDIT_OFFSET_BTN, name.c_str());
		height = 0;
		((IGUIButton*)button)->setIsPushButton(true);
	}

	if (type == EAT_UNKNOWN && label == L"Snap Offset")
	{
		propWidth = 90;	
		button = g->guienv->addButton(rect<s32>(x+95, y, x + 185, y + 20), parent, PROP_SNAP_TARGET_TO_EDGE_BTN, name.c_str());
		height = 20;		
	}

	if (type == EAT_UNKNOWN && label == L"Move to camera")
	{
		propWidth = 190;	
		button = g->guienv->addButton(rect<s32>(x, y, x + 190, y + 20), parent, PROP_EDIT_MOVE_TO_CAM, name.c_str());
		height = 20;		
	}

	if (type == EAT_UNKNOWN && label == L"Apply FOG")
	{
		propWidth = 190;	
		button = g->guienv->addButton(rect<s32>(x, y, x + 190, y + 20), parent, PROP_APPLY_FOG_BTN, name.c_str());
		height = 20;
	}

	if (type == EAT_UNKNOWN && label == L"Restart Effect")
	{
		propWidth = 190;	
		button = g->guienv->addButton(rect<s32>(x, y, x + 190, y + 20), parent, PROP_RESTART_EFFECT_BTN, name.c_str());
		height = 20;
	}

	switch (type)
	{
		case EAT_INT:
			if (name.c_str()[0] == L'$')
			{
				g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
				array<stringw> listArray = editor->getGameListArray(name.subString(1, name.size() - 1));
				for (u32 z = 0; z < listArray.size(); z ++)
					((IGUIComboBox*)edit)->addItem(listArray[z].c_str());
				height = 40;
			} 
			else if (name.c_str()[0] == L'@')
			{
				//g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				//false, false, parent, 1);
				//edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);				
				//for (u32 z = 0; z < sceneObject->m_Animations.size(); z ++)
				//	((IGUIComboBox*)edit)->addItem(sceneObject->m_Animations[z].name.c_str());
				height = 40;				
			}
			else if (name.c_str()[0] == L'^')
			{
				int pos = name.findNext(L'^', 1);
				stringw filter = L"";
				if (pos != -1)
				{
					filter = name.subString(pos + 1, name.size() - pos - 1);
				}

				g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
				((IGUIComboBox*)edit)->addItem(L"None");
				for (u32 z = 0; z < editor->m_SceneObjects.size(); z ++)
				{
					if (filter == L"" || filter == editor->m_SceneObjects[z]->m_UserData->getAttributeAsStringW("!GameType"))
					{
						stringw itemName = stringw(editor->m_SceneObjects[z]->m_SceneNode->getID()) +
							" - " + editor->m_SceneObjects[z]->m_UserData->getAttributeAsStringW("Name");
						((IGUIComboBox*)edit)->addItem(itemName.c_str());
					}
				}
				height = 40;
			}
			else if (name == L"MaterialType")
			{
				g->guienv->addStaticText(name.c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);				
				for (int z = 0; z < g->device->getVideoDriver()->getMaterialRendererCount(); z ++)
					((IGUIComboBox*)edit)->addItem(stringw(g->device->getVideoDriver()->getMaterialRendererName(z)).c_str());
				height = 40;				
			}
			else
			{
				g->guienv->addStaticText(name.c_str(), rect<s32>(x, y, x + 100, y + 20), 
					false, false, parent, 1);
				edit = g->guienv->addEditBox(L"", rect<s32>(x + 100, y, x + propWidth, y + 20), true,
					parent, 1);
				height = 20;
			}
			break;

		case EAT_FLOAT: 
			g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x + 100, y, x + propWidth, y + 20), true,
				parent, 1);
			height = 20;
			break;

		case EAT_STRING:
			if (name.c_str()[0] == L'$')
			{
				g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
				array<stringw> listArray = editor->getGameListArray(name.subString(1, name.size() - 1));
				for (u32 z = 0; z < listArray.size(); z ++)
					((IGUIComboBox*)edit)->addItem(listArray[z].c_str());
				height = 40;
			} 
			else if (name.c_str()[0] == L'@')
			{
				g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
				array<stringw> animNames = sceneObject->GetAnimationNames();
				for (u32 z = 0; z < animNames.size(); z ++)
					((IGUIComboBox*)edit)->addItem(animNames[z].c_str());

				button = g->guienv->addButton(rect<s32>(x, y + 40, x + 50, y + 60), parent, PROP_PLAY_BTN, L" Play ", L"Play");
				g->guienv->addCheckBox(false, rect<s32>(x + 55, y + 40, x + 150, y + 60), parent, PROP_LOOP_CHECK, L"Loop");
				staticText = g->guienv->addStaticText(L"Time", rect<s32>(x + 110, y + 40 , x + 180, y + 60), true, false, parent, 1);
				height = 60;
			}
			else
			{
				g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
					false, false, parent, 1);
				edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35), 
					true, parent, 1);
				height = 35;
			}
			break;

		case EAT_BOOL:
			g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
			edit = g->guienv->addCheckBox(false, rect<s32>(x + propWidth - 20, y, x + propWidth, y + 20), 
				parent, 1);
			height = 20;
			break;

		case EAT_VECTOR3D: 
			g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20),
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35),
				true, parent, 1);
			height = 35;
			break;

		case EAT_COLOR: 
			g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20),
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35),
				true, parent, 1);
			height = 35;
			break;

		case EAT_COLORF: 
			g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), false, false, 
				parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35), true,
				parent, 1);
			height = 35;
			break;
	}
	
	if (bReadOnly)
		edit->setEnabled(false);

	CProperty prop;

	prop.m_GUIElementEdit = edit;
	prop.m_GUIElementButton = button;
	prop.m_GUIElementStatic = staticText;
	prop.m_Name = name;
	prop.m_Type = (E_ATTRIBUTE_TYPE)type;
	prop.m_bUserData = bUserData;

	m_Properties.push_back(prop);

	height += 5;	//spacing
	return height;
}

IGUIListBox* CUserInterface::addCListBox(IGUIEnvironment* enviroment ,const core::rect<s32>& rectangle,
		IGUIElement* parent, s32 id, bool drawBackground)
{
	CListBox* listBox = new CListBox(enviroment, parent ? parent : (IGUIElement*)enviroment, id, rectangle,
		true, true, false);
	
	if (enviroment && enviroment->getSkin()->getSpriteBank())
	{
		listBox->setSpriteBank(g->guienv->getSkin()->getSpriteBank());
	}
	else if (g->guienv->getBuiltInFont() &&enviroment->getBuiltInFont()->getType() == EGFT_BITMAP)
	{
		listBox->setSpriteBank( ((IGUIFontBitmap*)enviroment->getBuiltInFont())->getSpriteBank());
	}

	listBox->drop();
	return listBox;

}
void CUserInterface::setSceneNodeVisible(int ID,bool bVisible)
{
	if(!bVisible)
	{
		int listSize = m_SceneGraphPropertiesInvisibleList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		m_SceneGraphPropertiesInvisibleList->insertItem(listSize, node->Text.c_str(), -1);
		int i;
		listSize = m_SceneGraphPropertiesVisibleList->getItemCount();
		node = m_sceneGraphTree->FindNode(ID);
		for(i =0;i<listSize;i++)
		{
			stringw list = m_SceneGraphPropertiesVisibleList->getListItem(i);
			if(list == node->Text)
			{
				m_SceneGraphPropertiesVisibleList->removeItem(i);
				break;
			}
		}
	}
	else
	{		
		int listSize = m_SceneGraphPropertiesVisibleList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		m_SceneGraphPropertiesVisibleList->insertItem(listSize, node->Text.c_str(), -1);

		int i;
		listSize = m_SceneGraphPropertiesInvisibleList->getItemCount();
		node = m_sceneGraphTree->FindNode(ID);
		for(i =0;i<listSize;i++)
		{
			stringw list = m_SceneGraphPropertiesInvisibleList->getListItem(i);
			if(list == node->Text)
			{
				m_SceneGraphPropertiesInvisibleList->removeItem(i);
				break;
			}
		}
	}
}

void CUserInterface::setSceneNodeLocked(int ID,bool bLocked)
{
	if(bLocked)
	{
		int listSize = m_SceneGraphPropertiesLockedList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		m_SceneGraphPropertiesLockedList->insertItem(listSize, node->Text.c_str(), -1);		
	}
	/*else
	{	
		int i;
		int listSize = m_SceneGraphPropertiesLockedList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		for(i =0;i<listSize;i++)
		{
			stringw list = m_SceneGraphPropertiesLockedList->getListItem(i);
			if(list == node->Text)
			{
				m_SceneGraphPropertiesLockedList->removeItem(i);
				break;
			}
		}
	}*/
}

void CUserInterface::removeSceneNodeFromList(int ID, bool bVisible)
{
	if(bVisible)
	{
		int i;
		int	listSize = m_SceneGraphPropertiesVisibleList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		for(i =0;i<listSize;i++)
		{
			stringw list = m_SceneGraphPropertiesVisibleList->getListItem(i);
			if(list == node->Text)
			{
				m_SceneGraphPropertiesVisibleList->removeItem(i);
				break;
			}
		}
	}
	else
	{		
		int i;
		int listSize = m_SceneGraphPropertiesInvisibleList->getItemCount();
		TreeNode* node = m_sceneGraphTree->FindNode(ID);
		for(i =0;i<listSize;i++)
		{
			stringw list = m_SceneGraphPropertiesInvisibleList->getListItem(i);
			if(list == node->Text)
			{
				m_SceneGraphPropertiesInvisibleList->removeItem(i);
				break;
			}
		}
	}
}
void CUserInterface::clearPropertiesWindow()
{
	m_linkChangedProp = NULL ;
	m_Properties.clear();
	m_TemplateProperties.clear();
	rect<s32> pos = m_PropertiesWindow->getRelativePosition();
	//if (m_PropertiesWindow)
	//	m_PropertiesWindow->remove();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + 43;

	int activeTab = m_PropertiesTabs->getActiveTab();
	m_PropertiesTabs->removeChild(m_PropertiesStandardTab);
	m_PropertiesTabs->removeChild(m_PropertiesCustomTab);
	m_PropertiesTabs->addTab(L"standard");
	m_PropertiesTabs->addTab(L"custom");
	m_PropertiesStandardTab = m_PropertiesTabs->getTab(0);
	m_PropertiesCustomTab = m_PropertiesTabs->getTab(1);
	m_PropertiesTabs->setActiveTab(activeTab);
	m_PropertiesWindow->setRelativePosition(pos);
}

void CUserInterface::createSelectedObjectProperties()
{
	ISceneNode* node = editor->getSelectedNode();
	
	if (!node || editor->m_SaveLoadProgressDraw)
	{
		return;
	}
	CSceneObject* sceneObject = 0;
	
	sceneObject = editor->getSceneObjectFromID(node->getID());
	
	if (!sceneObject)
	{
		return;
	}
	clearPropertiesWindow();
	int standardY = 5;
	int customY = 5;
	stringw typeS;

//first show standart properties
	ESCENE_NODE_TYPE type = node->getType();
	switch (type)
	{
		case ESNT_CUBE:			
		case ESNT_SPHERE:
		case ESNT_TERRAIN:
			//position, rotation, scale, texture
			standardY += createProperty(sceneObject, L"Position", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Rotation", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Scale", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			typeS = sceneObject->m_UserData->getAttributeAsStringW("!GameType");
			typeS.make_lower();
			if (typeS != L"triggerzone" && typeS != "waypoint")
				standardY += createProperty(sceneObject, L"Texture", EAT_STRING, 5, standardY, false, m_PropertiesStandardTab);
			if (sceneObject->m_SceneNode->getMaterialCount() > 0)
				standardY += createProperty(sceneObject, L"MaterialType", EAT_INT, 5, standardY, false, m_PropertiesStandardTab);
			break;
		
		case ESNT_SKY_BOX:
			//it is impossible to edit skybox textures on runtime
			break;
		case ESNT_BILLBOARD:
			standardY += createProperty(sceneObject, L"Position", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Rotation", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Scale", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Width", EAT_FLOAT, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Height", EAT_FLOAT, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Texture", EAT_STRING, 5, standardY, false, m_PropertiesStandardTab);
			if (sceneObject->m_SceneNode->getMaterialCount() > 0)
				standardY += createProperty(sceneObject, L"MaterialType", EAT_INT, 5, standardY, false, m_PropertiesStandardTab);
			break;
		case ESNT_MESH:			
		case ESNT_ANIMATED_MESH:			
		//case ESNT_OCT_TREE:
			//position, rotation, scale
			standardY += createProperty(sceneObject, L"Position", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Rotation", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Scale", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			if (sceneObject->m_SceneNode->getMaterialCount() > 0)
				standardY += createProperty(sceneObject, L"MaterialType", EAT_INT, 5, standardY, false, m_PropertiesStandardTab);
			break;
		default:
			standardY += createProperty(sceneObject, L"Position", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Rotation", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
			standardY += createProperty(sceneObject, L"Scale", EAT_VECTOR3D, 5, standardY, false, m_PropertiesStandardTab);
		break;
	}

	//cycle trought userData properties
	
	const c8* attName;

	//DEBUG_OUT(" ------------- \n" );

	for (u32 i = 0; i < sceneObject->m_UserData->getAttributeCount(); i ++)
	{
		attName = sceneObject->m_UserData->getAttributeName(i);
		
		//DEBUG_OUT(" test %s %d , %d \n" , attName , standardY , customY);

		if (attName[0] != '#')
		{
			if (stringc("Name") == sceneObject->m_UserData->getAttributeName(i) ||
				stringc("!GameType") == sceneObject->m_UserData->getAttributeName(i))
			{
				standardY += createProperty(sceneObject, sceneObject->m_UserData->getAttributeName(i), 
					sceneObject->m_UserData->getAttributeType(i), 5, standardY, true, m_PropertiesStandardTab);
			}
			else
			{
				customY += createProperty(sceneObject, sceneObject->m_UserData->getAttributeName(i), 
					sceneObject->m_UserData->getAttributeType(i), 5, customY, true, m_PropertiesCustomTab);
			}
		}
	}

	if (sceneObject->m_UserData->getAttributeAsString("!GameType") == "Cinematic")
	{
		customY += createProperty(sceneObject, L"Edit Cinematic", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
	}

	if (sceneObject->m_UserData->getAttributeAsString("!GameType") == "CamCtrlPoint")
	{
		createProperty(sceneObject, L"Edit Offset", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
		customY += createProperty(sceneObject, L"Snap Offset", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
	}

	if (sceneObject->m_UserData->getAttributeAsString("!GameType") == "SpiderMan")
	{
		customY += createProperty(sceneObject, L"Move to camera", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
	}

	if (sceneObject->m_UserData->getAttributeAsString("!GameType") == "FOG")
	{
		customY += createProperty(sceneObject, L"Apply FOG", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
	}

	if (sceneObject->m_UserData->getAttributeAsString("!GameType") == "Effect")
	{
		customY += createProperty(sceneObject, L"Restart Effect", EAT_UNKNOWN, 5, customY, true, m_PropertiesCustomTab);
	}

	int y = standardY;
	if (customY > y) y = customY;

	rect<s32> pos = m_PropertiesTabs->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesTabs->setRelativePosition(pos);
	
	pos = m_PropertiesCustomTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesCustomTab->setRelativePosition(pos);

	pos = m_PropertiesStandardTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesStandardTab->setRelativePosition(pos);

	//TOOD: resize window after creating controls
	pos = m_PropertiesWindow->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesWindow->setRelativePosition(pos);
	
	//DEBUG_OUT(" m_PropertiesWindow %d ,%d \n" , pos.getWidth() , pos.getHeight());

	//DEBUG_OUT(" m_PropertiesStandardTab %d ,%d \n" , pos.getWidth() , pos.getHeight());

	//DEBUG_OUT(" m_PropertiesCustomTab %d ,%d \n" , pos.getWidth() , pos.getHeight());
	//
	//DEBUG_OUT(" m_PropertiesTabs %d ,%d \n" , pos.getWidth() , pos.getHeight());

	updateProperties();
}

void CUserInterface::createSelectedTemplateProperties()
{
	int customY = 5;
	const c8* attName;

	clearPropertiesWindow();
	
	CGameObject *pTemplateObject = NULL;

	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
	int sel = lb->getSelected();
	if (sel != -1)
	{
		pTemplateObject = editor->m_GameTemplates[sel];
	}

	if (!pTemplateObject) return;

	for (u32 i = 0; i < pTemplateObject->m_Attributes->getAttributeCount(); i ++)
	{
		attName = pTemplateObject->m_Attributes->getAttributeName(i);
		
		//DEBUG_OUT(" test %s %d , %d \n" , attName , standardY , customY);

		if (attName[0] != '#' && attName[0] != '@' && attName[0] != '!' && attName[0] != '^')
		{
			customY += createProperty(pTemplateObject->m_Attributes->getAttributeName(i), 
				pTemplateObject->m_Attributes->getAttributeType(i), 5, customY, m_PropertiesCustomTab, &m_TemplateProperties);
		}
	}

	int y = customY;

	rect<s32> pos = m_PropertiesTabs->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesTabs->setRelativePosition(pos);
	
	pos = m_PropertiesCustomTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesCustomTab->setRelativePosition(pos);

	pos = m_PropertiesStandardTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesStandardTab->setRelativePosition(pos);

	//TOOD: resize window after creating controls
	pos = m_PropertiesWindow->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + y + 50;
	m_PropertiesWindow->setRelativePosition(pos);

	updateProperties(pTemplateObject->m_Attributes, &m_TemplateProperties);
}

stringw CUserInterface::vector3DToString(const vector3df* vector, u16 precision)
{
	stringw result = "";
	
	wchar_t tmp[20];

	swprintf(tmp, 20, L"%0.3f", vector->X);
	result += tmp;
	result += L",";
	swprintf(tmp, 20, L"%0.3f", vector->Y);
	result += tmp;
	result += L",";	
	swprintf(tmp, 20, L"%0.3f", vector->Z);
	result += tmp;

	return result;
}

stringw CUserInterface::colorToString(const SColor* color)
{
	stringw result = stringw(color->getAlpha()) + L"," +
		stringw(color->getRed()) + L"," + 
		stringw(color->getGreen()) + L"," +
		stringw(color->getBlue());

	return result;
}

int CUserInterface::stringToInt(stringw str)
{
	int result;

	int i = _snwscanf_s(str.c_str(), str.size(), L"%d", &result);
	
	return result;
}

f32 CUserInterface::stringToFloat(stringw str)
{
	f32 result;

	int i = _snwscanf_s(str.c_str(), str.size(), L"%f", &result);
	
	return result;
}

vector3df CUserInterface::stringToVector3D(stringw str)
{
	vector3df result;
	
	int i = _snwscanf_s(str.c_str(), str.size(), L"%f,%f,%f", &result.X, &result.Y, &result.Z);

	return result;
}

SColor CUserInterface::stringToColor(stringw str)
{
	SColor result;
	u32 a, r, g, b = 255;

	int i = _snwscanf_s(str.c_str(), str.size(), L"%u,%u,%u,%u", &a, &r, &g, &b);

	result.set(a, r, g, b);

	return result;
}

//populate current prop. values from object when edited	
void CUserInterface::updateProperties()
{
	ISceneNode* selectedNode = editor->getSelectedNode();
	if (!selectedNode)
		return;

	CSceneObject* sceneObject = editor->getSceneObjectFromID(selectedNode->getID());
	
	if (!sceneObject)
		return;
	
	m_CinematicEditor.setObjectProperties();

	stringw valueStr;
	//editor->m_HasActiveZone = false;	

	for (u32 i = 0; i < m_Properties.size(); i ++)
	{
		//standart types first
		valueStr = "";
		
		if (!m_Properties[i].m_bUserData)
		{
			if (m_Properties[i].m_Name == L"Position")
				valueStr = vector3DToString(&selectedNode->getPosition(), 5);

			if (m_Properties[i].m_Name == L"Rotation")
			{
				vector3df vec;
				//selectedNode->getRotation().toEuler(vec);
				vec = selectedNode->getRotation();
				vec *= vector3df(180.0f/PI, 180.0f/PI, 180.0f/PI);				
				valueStr = vector3DToString(&vec, 5);
			}

			if (m_Properties[i].m_Name == L"Scale")
				valueStr = vector3DToString(&selectedNode->getScale(), 5);
					
			if (m_Properties[i].m_Name == L"Color")
				valueStr = colorToString(&selectedNode->getMaterial(0).EmissiveColor);

			if (m_Properties[i].m_Name == L"Texture")
			{
				ITexture* texture = selectedNode->getMaterial(0).getTexture(0);
				if (texture)
					valueStr = texture->getName();
			}
			
			if (m_Properties[i].m_Name == L"MaterialType")
			{
				u32 z = 0;
				if (selectedNode->getMaterialCount() > 0)
					z = selectedNode->getMaterial(0).MaterialType;
				if (m_Properties[i].m_GUIElementEdit)
					((IGUIComboBox*)m_Properties[i].m_GUIElementEdit)->setSelected(z);
				continue;
			}
			
			if (selectedNode->getType() == ESNT_BILLBOARD)
			{
				dimension2d<f32> size = (dynamic_cast<IBillboardSceneNode*>(selectedNode))->getSize();
				if (m_Properties[i].m_Name == L"Width")				
					valueStr = stringw(size.Width);
				if (m_Properties[i].m_Name == L"Height")
					valueStr = stringw(size.Height);				
			}			
		}
		else
		{		
			switch (m_Properties[i].m_Type)
			{
				case EAT_INT:
					valueStr = stringw(sceneObject->m_UserData->getAttributeAsInt( stringc(m_Properties[i].m_Name.c_str()).c_str()));
					break;

				case EAT_BOOL:
					if (m_Properties[i].m_GUIElementEdit)
						((IGUICheckBox*)m_Properties[i].m_GUIElementEdit)->setChecked(
						sceneObject->m_UserData->getAttributeAsBool( stringc(m_Properties[i].m_Name.c_str()).c_str()));
					break;					
				
				case EAT_FLOAT: 
					valueStr = stringw(sceneObject->m_UserData->getAttributeAsFloat(stringc(m_Properties[i].m_Name.c_str()).c_str()));
					break;				
				
				case EAT_VECTOR3D:
					{
						vector3df vec = sceneObject->m_UserData->getAttributeAsVector3d( stringc(m_Properties[i].m_Name.c_str()).c_str() );
						valueStr = vector3DToString(&vec, 5);
						//if (m_Properties[i].m_Name == L"ActiveZonePosition")
						//{
						//	editor->m_HasActiveZone = true;	
						//	editor->m_SelectedNodeActiveZonePos = vec;
						//}

						//if (m_Properties[i].m_Name == L"ActiveZoneScale")
						//{
						//	editor->m_HasActiveZone = true;	
						//	editor->m_SelevtedNodeActiveZoneScale = vec;
						//}

					}
					break;

				case EAT_STRING:
					valueStr = sceneObject->m_UserData->getAttributeAsStringW(stringc(m_Properties[i].m_Name.c_str()).c_str());

					if (m_Properties[i].m_Name.c_str()[0] == L'$')
					{
						array<stringw> listArray = editor->getGameListArray(m_Properties[i].m_Name.subString(1, m_Properties[i].m_Name.size() - 1));
						for (u32 z = 0; z < listArray.size(); z ++)
						{
							if (listArray[z] == stringw(valueStr))
							{
								valueStr = stringw(z);
								break;
							}
						}
					}
					break;

				case EAT_COLOR:
					SColor color = sceneObject->m_UserData->getAttributeAsColor( stringc(m_Properties[i].m_Name.c_str()).c_str());
					valueStr = colorToString(&color);
					break;
			}
		}

		if (m_Properties[i].m_GUIElementEdit)
		{
			if (m_Properties[i].m_Name.c_str()[0] == L'$')
			{
				((IGUIComboBox*)m_Properties[i].m_GUIElementEdit)->setSelected(stringToInt(valueStr));
			}
			else if (m_Properties[i].m_Name.c_str()[0] == L'@')
			{
				array<stringw> animNames = sceneObject->GetAnimationNames();
				//bool bFound = false;
				for (u32 j=0; j < animNames.size(); j++)
				{
					if (valueStr == animNames[j])
					{
						((IGUIComboBox*)m_Properties[i].m_GUIElementEdit)->setSelected(j);
						//bFound = true;
						break;
					}
				}

				IGUICheckBox* check = (IGUICheckBox*)m_PropertiesWindow->getElementFromId(PROP_LOOP_CHECK, true);
//				check->setChecked(sceneObject->GetCurrentAnim().m_loop);

				//if (!bFound)
				//{
				//	stringw strError = L"Object ID '";
				//	strError += sceneObject->m_SceneNode->getID();
				//	strError += L"' cannot find anim '";
				//	strError += valueStr;
				//	strError += "'!!!";
				//	g->guienv->addMessageBox(L"Error!", strError.c_str(), false);
				//}
			}
			else if (m_Properties[i].m_Name.c_str()[0] == L'^')			
			{
				int val = stringToInt(valueStr);
				if (val < 0)				
					((IGUIComboBox*)m_Properties[i].m_GUIElementEdit)->setSelected(0);
				else
				{
					int pos = m_Properties[i].m_Name.findNext(L'^', 1);
					stringw filter = L"";
					if (pos != -1)
					{
						filter = m_Properties[i].m_Name.subString(pos + 1, m_Properties[i].m_Name.size() - pos - 1);
					}

					int index = 0;

					for (u32 z = 0; z < editor->m_SceneObjects.size(); z ++)
					{
						if (filter == L"" || filter == editor->m_SceneObjects[z]->m_UserData->getAttributeAsStringW("!GameType"))
						{
							if (editor->m_SceneObjects[z]->m_SceneNode->getID() == stringToInt(valueStr))					
							{
								((IGUIComboBox*)m_Properties[i].m_GUIElementEdit)->setSelected(index + 1);
								break;
							}

							index++;
						}
					}
				}
			}
			else
				m_Properties[i].m_GUIElementEdit->setText(valueStr.c_str());
		}
	}
}

bool CUserInterface::propertyEditBoxEnter(const SEvent& event)
{
	IGUIEditBox* editBox = (IGUIEditBox*)event.GUIEvent.Caller;

	CProperty* changedProp = 0;

	for (u32 i = 0; i < m_Properties.size(); i ++)	
		if (m_Properties[i].m_GUIElementEdit == editBox)
		{
			changedProp = &m_Properties[i];
			break;
		}
	
	if (changedProp)
	{
		ISceneNode* selectedNode = editor->getSelectedNode();
		if (!selectedNode)
			return false;

		CSceneObject* sceneObject = editor->getSceneObjectFromID(selectedNode->getID());
		//standart once
		if (!changedProp->m_bUserData)
		{
			if (changedProp->m_Name == L"Position")
				editor->AddCommand(new CMoveCommand(selectedNode->getID(), selectedNode->getPosition(), stringToVector3D(editBox->getText())));

			if (changedProp->m_Name == L"Rotation")
			{
				vector3df vec = stringToVector3D(editBox->getText());
				vec *= vector3df(PI/180.0f, PI/180.0f, PI/180.0f);
				editor->AddCommand(new CRotateCommand(selectedNode->getID(), selectedNode->getRotation(), quaternion(vec)));
			}

			if (changedProp->m_Name == L"Scale")
			{
				editor->AddCommand(new CScaleCommand(selectedNode->getID(), selectedNode->getScale(), stringToVector3D(editBox->getText())));
			}
					
			if (changedProp->m_Name == L"Color")
			{
				editor->AddCommand(new CSetColorCommand(selectedNode->getID(),
					selectedNode->getMaterial(0).EmissiveColor, stringToColor(editBox->getText())));
			}

		

			if (selectedNode->getType() == ESNT_BILLBOARD)
			{
				dimension2d<f32> oldSize = (dynamic_cast<IBillboardSceneNode*>(selectedNode))->getSize();
				dimension2d<f32> newSize = oldSize;
				if (changedProp->m_Name == L"Width")				
					newSize.Width = stringToFloat(editBox->getText());
				if (changedProp->m_Name == L"Height")
					newSize.Height = stringToFloat(editBox->getText());
				if (oldSize.Width != newSize.Width || oldSize.Height != newSize.Height)
					editor->AddCommand(new CSetSizeCommand(selectedNode->getID(), oldSize, newSize));
			}			
		}	
		else
		{
			if (changedProp->m_Name == L"Name")
			{
				editor->AddCommand(new CSetNameCommand(selectedNode->getID(),
					sceneObject->m_UserData->getAttributeAsStringW("Name"), editBox->getText()));
			}
			else if (changedProp->m_Name == L"AnimationFile")
			{
				editor->AddCommand(new CSetAnimationFileCommand(selectedNode->getID(),editBox->getText()));
			}	
			else if (changedProp->m_Name == L"MeshFile")
			{
				editor->AddCommand(new CSetMeshFileCommand(selectedNode->getID(),editBox->getText()));
			}
			else if (changedProp->m_Name.find("TextureFile") >=0 )
			{										
				editor->AddCommand(new CSetTextureCommand(selectedNode->getID(), changedProp->m_Name.c_str(), editBox->getText() ));					
			}
			else if (changedProp->m_Name == L"Size")
			{
				f32 crtSize = sceneObject->m_UserData->getAttributeAsFloat("Size");
				f32 crtAngle = sceneObject->m_UserData->getAttributeAsFloat("Angle");
				editor->AddCommand(new CSetTriPrismParamsCommand(selectedNode->getID(), crtSize, stringToFloat(editBox->getText()), crtAngle, crtAngle ));
			}
			else if (changedProp->m_Name == L"Angle")
			{
				f32 crtSize = sceneObject->m_UserData->getAttributeAsFloat("Size");
				f32 crtAngle = sceneObject->m_UserData->getAttributeAsFloat("Angle");
				editor->AddCommand(new CSetTriPrismParamsCommand(selectedNode->getID(), crtSize, crtSize, crtAngle, stringToFloat(editBox->getText()) ));
			}
			else
			{
				if (changedProp->m_Type == EAT_COLOR)
				{
					editor->AddCommand(new CSetColorAttributeCommand(selectedNode->getID(),
						stringc(changedProp->m_Name.c_str()), stringToColor(editBox->getText())));
				}
				else
				{
					editor->AddCommand(new CSetStringAttributeCommand(selectedNode->getID(),
						stringc(changedProp->m_Name.c_str()), editBox->getText()));
				}
			}
		}
		return true;
	}

	//check template properties
	for (u32 i = 0; i < m_TemplateProperties.size(); i ++)	
		if (m_TemplateProperties[i].m_GUIElementEdit == editBox)
		{
			changedProp = &m_TemplateProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		IAttributes* pAttr = editor->m_GameTemplates[sel]->m_Attributes;

		if (pAttr->getAttributeType(stringc(changedProp->m_Name.c_str()).c_str()) == EAT_COLOR)
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), stringToColor(editBox->getText()));
		}
		else
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), editBox->getText());
		}

		return true;
	}

	//check particle system properies
	for (u32 i = 0; i < m_PSProperties.size(); i ++)	
		if (m_PSProperties[i].m_GUIElementEdit == editBox)
		{
			changedProp = &m_PSProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

		int sel_ps = lb->getSelected();
		
		if (sel_ps == -1) return false;

		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		ISceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];
		pNode->serializeAttributes(pAttr);

		if (pAttr->getAttributeType(stringc(changedProp->m_Name.c_str()).c_str()) == EAT_COLOR)
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), stringToColor(editBox->getText()));
		}
		else
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), editBox->getText());
		}

		pNode->deserializeAttributes(pAttr);

		pAttr->drop();
		return true;
	}

	//check affector properies
	for (u32 i = 0; i < m_AffectorProperties.size(); i ++)	
		if (m_AffectorProperties[i].m_GUIElementEdit == editBox)
		{
			changedProp = &m_AffectorProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IFpsParticleAffector* pAffector = getSelectedAffector();
		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		pAffector->serializeAttributes(pAttr);

		if (pAttr->getAttributeType(stringc(changedProp->m_Name.c_str()).c_str()) == EAT_COLOR)
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), stringToColor(editBox->getText()));
		}
		else
		{
			pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), editBox->getText());
		}

		pAffector->deserializeAttributes(0, pAttr);

		pAttr->drop();
		return true;
	}

	//check material properties
	for (u32 i = 0; i < m_MatProperties.size(); i ++)	
		if (m_MatProperties[i].m_GUIElementEdit == editBox)
		{
			changedProp = &m_MatProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

		int sel_ps = lb->getSelected();
		
		if (sel_ps == -1) return false;

		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];
		//pNode->serializeAttributes(pAttr);

		//pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), editBox->getText());

		if (stringc(changedProp->m_Name.c_str()) == stringc("Texture"))
		{
			ITexture* pTexture = g->driver->getTexture(editBox->getText());
			pNode->setMaterialFlag(video::EMF_LIGHTING, false);
			pNode->setMaterialTexture(0, pTexture);
			//pNode->setMaterialType(EMT_FPS_ADD);
			
			if(pTexture==0)
			{
				CSprite* spr = CSpriteManager::instance()->GetSprite("effects.bsprite");
				pTexture = spr->GetTexture();
				pNode->setMaterialTexture(0, pTexture);
				pNode->setUVRect(spr->GetModuleUVRect(0,0));
			}
		}

		//pNode->deserializeAttributes(pAttr);

		pAttr->drop();
		return true;
	}

	return false;
}

bool CUserInterface::propertyButtonPressed(const SEvent& event)
{
	IGUIButton* button = (IGUIButton*)event.GUIEvent.Caller;
	CProperty* changedProp = 0;
	stringw caption;

	for (u32 i = 0; i < m_Properties.size(); i ++)	
		if (m_Properties[i].m_GUIElementButton == button)
		{
			changedProp = &m_Properties[i];
			break;
		}
	
	if (changedProp)
	{
		caption = stringw(L"Open ") + changedProp->m_Name;
		g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
		g->guienv->addFileOpenDialog(caption.c_str(), true, 0, FILE_PROP_FILE_OPEN_DIALOG);
		m_FileOpenProp = changedProp;
		return true;
	}

	//check template properties
	for (u32 i = 0; i < m_TemplateProperties.size(); i ++)	
		if (m_TemplateProperties[i].m_GUIElementButton == button)
		{
			changedProp = &m_TemplateProperties[i];
			break;
		}
	
	if (changedProp)
	{
		caption = stringw(L"Open ") + changedProp->m_Name;
		g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
		g->guienv->addFileOpenDialog(caption.c_str(), true, 0, FILE_PROP_FILE_OPEN_DIALOG);
		m_FileOpenProp = changedProp;
		return true;
	}

	//check material properties
	for (u32 i = 0; i < m_MatProperties.size(); i ++)	
		if (m_MatProperties[i].m_GUIElementButton == button)
		{
			changedProp = &m_MatProperties[i];
			break;
		}
	
	if (changedProp)
	{
		caption = stringw(L"Open ") + changedProp->m_Name;
		g->device->getFileSystem()->changeWorkingDirectoryTo(m_UserBrowsePath.c_str());
		g->guienv->addFileOpenDialog(caption.c_str(), true, 0, FILE_PROP_FILE_OPEN_DIALOG);
		m_FileOpenProp = changedProp;

		m_bUseEditorRelativePath = true;

		return true;
	}

	return false;
}

bool CUserInterface::propertyComboBoxChanged(const SEvent& event)
{
	IGUIComboBox* comboBox = (IGUIComboBox*)event.GUIEvent.Caller;

	CProperty* changedProp = 0;

	for (u32 i = 0; i < m_Properties.size(); i ++)	
		if (m_Properties[i].m_GUIElementEdit == comboBox)
		{
			changedProp = &m_Properties[i];
			break;
		}
	
	if (changedProp)
	{
		ISceneNode* selectedNode = editor->getSelectedNode();
		if (!selectedNode)
			return false;

		CSceneObject* sceneObject = editor->getSceneObjectFromID(selectedNode->getID());

		if (sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("Effect") && changedProp->m_Name == stringw("$EffectType"))
		{
			editor->SetObjectEffectType(selectedNode, comboBox->getItem(comboBox->getSelected()));
		}
		else if( sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("Bonus") && changedProp->m_Name == stringw("$EffectType"))
		{
			editor->SetObjectEffectType(selectedNode, comboBox->getItem(comboBox->getSelected()));
		}
		else if( sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("EffectDamage") && changedProp->m_Name == stringw("$EffectType"))
		{
			editor->SetObjectEffectType(selectedNode, comboBox->getItem(comboBox->getSelected()));
		}
		else if( sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("DropArea") && changedProp->m_Name == stringw("$EffectType"))
		{
			editor->SetObjectEffectType(selectedNode, comboBox->getItem(comboBox->getSelected()));
		}
		else if( sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("DropObject") && changedProp->m_Name == stringw("$EffectType"))
		{
			;
		}

		if (sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("Enemy") && changedProp->m_Name == stringw("$EnemyType"))
		{
			//if ()
			{
				//ms HACK ENEMY
				for (u32 i = 7; i < 13; i ++)	
				{
					if (m_Properties[i].m_GUIElementEdit)
					{											
						m_Properties[i].m_GUIElementEdit->setEnabled( comboBox->getSelected() == 0 );
					}
				}
			}
		}

		//comboBox only for user data for now
		if (changedProp->m_bUserData)
		{
			if (changedProp->m_Name.c_str()[0] == L'^')
			{
				int id = -1;
				if (comboBox->getSelected() != 0)
				{
					int pos = changedProp->m_Name.findNext(L'^', 1);
					stringw filter = L"";
					if (pos != -1)
					{
						filter = changedProp->m_Name.subString(pos + 1, changedProp->m_Name.size() - pos - 1);
					}

					int nb = 0;
					CSceneObject* pObject = NULL;
					for (u32 i = 0; i < editor->m_SceneObjects.size(); i++)
					{
						if (filter == L"" || filter == editor->m_SceneObjects[i]->m_UserData->getAttributeAsStringW("!GameType"))
						{
							if (nb == comboBox->getSelected() - 1)
							{
								pObject = editor->m_SceneObjects[i];
								break;
							}
							nb++;
						}
					}

					id = pObject->m_SceneNode->getID();
				}

				editor->AddCommand(new CSetIntAttributeCommand(sceneObject->m_SceneNode->getID(),
					stringc(changedProp->m_Name.c_str()), id));
	
			}
			else if (changedProp->m_Name.c_str()[0] == L'@')
			{
				editor->AddCommand(new CSetStringAttributeCommand(sceneObject->m_SceneNode->getID(),
					stringc(changedProp->m_Name.c_str()), comboBox->getItem(comboBox->getSelected())));

//				sceneObject->SetAnim(comboBox->getSelected() - 1);

				IGUICheckBox* check = (IGUICheckBox*)m_PropertiesWindow->getElementFromId(PROP_LOOP_CHECK, true);
				check->setChecked(false);

				editor->AddCommand(new CSetBoolAttributeCommand(sceneObject->m_SceneNode->getID(), 
					stringc(changedProp->m_Name.c_str()), check->isChecked()));

				//set time here 
				if (changedProp->m_GUIElementStatic)
				{
					stringw text = L"";
					text += sceneObject->GetCurrentAnimationTime(comboBox->getSelected() - 1);
					changedProp->m_GUIElementStatic->setText(text.c_str());
				}
			}
			else if (changedProp->m_Name.c_str()[0] == L'$')
			{
				if (changedProp->m_Type == EAT_INT)
				{
					editor->AddCommand(new CSetIntAttributeCommand(sceneObject->m_SceneNode->getID(),
						stringc(changedProp->m_Name.c_str()), comboBox->getSelected()));
				}
				else if (changedProp->m_Type == EAT_STRING)
				{
					editor->AddCommand(new CSetStringAttributeCommand(sceneObject->m_SceneNode->getID(),
						stringc(changedProp->m_Name.c_str()), comboBox->getItem(comboBox->getSelected())));
				}
			}
			else
			{
				editor->AddCommand(new CSetIntAttributeCommand(sceneObject->m_SceneNode->getID(),
					stringc(changedProp->m_Name.c_str()), comboBox->getSelected()));
			}
		}
		else
		{
			if (changedProp->m_Name == L"MaterialType")
			{
				editor->AddCommand(new CSetMaterialTypeCommand(
					sceneObject->m_SceneNode->getID(), (E_MATERIAL_TYPE)comboBox->getSelected()));
			}
		}
		return true;
	}

	//check template properties
	for (u32 i = 0; i < m_TemplateProperties.size(); i ++)	
		if (m_TemplateProperties[i].m_GUIElementEdit == comboBox)
		{
			changedProp = &m_TemplateProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		IAttributes* pAttr = editor->m_GameTemplates[sel]->m_Attributes;

		if (changedProp->m_Name.c_str()[0] == L'$')
		{
			if (changedProp->m_Type == EAT_INT)
			{
				pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), comboBox->getSelected());
			}
			else if (changedProp->m_Type == EAT_STRING)
			{
				pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), comboBox->getItem(comboBox->getSelected()));
			}
		}

		return true;
	}

	//check material properties
	for (u32 i = 0; i < m_MatProperties.size(); i ++)	
		if (m_MatProperties[i].m_GUIElementEdit == comboBox)
		{
			changedProp = &m_MatProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

		int sel_ps = lb->getSelected();
		
		if (sel_ps == -1) return false;

		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];
		//pNode->serializeAttributes(pAttr);

		//pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), editBox->getText());

		if (stringc(changedProp->m_Name.c_str()) == stringc("MaterialType"))
		{
			pNode->setMaterialType((E_MATERIAL_TYPE)comboBox->getSelected());
		}

		if (stringc(changedProp->m_Name.c_str()) == stringc("$SpriteFrameName"))		
		{
			irr::core::stringc frameName = comboBox->getText();
			pNode->setSpriteFrameName(frameName);						
			int frameID = g->FindFrameIDByName(frameName.c_str());
			if(frameID<0)
				frameID=0;
			CSprite* spr = CSpriteManager::instance()->GetSprite("effects.bsprite");																			
			pNode->setUVRect(spr->GetModuleUVRect(frameID,0));	
		}


		//pNode->deserializeAttributes(pAttr);

		pAttr->drop();
		return true;
	}

	return false;
}

void CUserInterface::updateWindowsPosition()
{
	if (m_LastScreenSize != g->driver->getScreenSize())
	{		
		m_LastScreenSize = g->driver->getScreenSize();
		rect<s32> rect;

		rect = m_ToolsWindow->getRelativePosition();		
		rect.UpperLeftCorner.X = m_LastScreenSize.Width - m_ToolsWindow->getRelativePosition().getWidth();
		rect.UpperLeftCorner.Y = 21;
		rect.LowerRightCorner.X = m_LastScreenSize.Width;
		rect.LowerRightCorner.Y = 21 + m_ToolsWindow->getRelativePosition().getHeight();
		m_ToolsWindow->setRelativePosition(rect);

		//rect = m_HistoryWindow->getRelativePosition();
		//rect.UpperLeftCorner.X = m_ToolsWindow->getRelativePosition().UpperLeftCorner.X;
		//rect.UpperLeftCorner.Y = m_ToolsWindow->getRelativePosition().LowerRightCorner.Y;
		//rect.LowerRightCorner.X = rect.UpperLeftCorner.X + m_HistoryWindow->getRelativePosition().getWidth();
		//rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_HistoryWindow->getRelativePosition().getHeight();
		//m_HistoryWindow->setRelativePosition(rect);

		//rect = m_PropertiesWindow->getRelativePosition();
		//rect.UpperLeftCorner.X = m_HistoryWindow->getRelativePosition().UpperLeftCorner.X;
		//rect.UpperLeftCorner.Y = m_HistoryWindow->getRelativePosition().LowerRightCorner.Y;
		//rect.LowerRightCorner.X = rect.UpperLeftCorner.X + m_PropertiesWindow->getRelativePosition().getWidth();
		//rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_PropertiesWindow->getRelativePosition().getHeight();
		//m_PropertiesWindow->setRelativePosition(rect);

		rect = m_PropertiesWindow->getRelativePosition();
		rect.UpperLeftCorner.X = m_ToolsWindow->getRelativePosition().UpperLeftCorner.X;
		rect.UpperLeftCorner.Y = m_ToolsWindow->getRelativePosition().LowerRightCorner.Y;
		rect.LowerRightCorner.X = rect.UpperLeftCorner.X + m_PropertiesWindow->getRelativePosition().getWidth();
		rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_PropertiesWindow->getRelativePosition().getHeight();
		m_PropertiesWindow->setRelativePosition(rect);

		m_CinematicEditor.updateWindowPosition();
	}
}

bool CUserInterface::propertyCheckBoxChanged(const SEvent& event)
{
	IGUICheckBox* checkBox = (IGUICheckBox*)event.GUIEvent.Caller;

	if (checkBox->getID() == PROP_LOOP_CHECK)
	{
		ISceneNode* selectedNode = editor->getSelectedNode();
		CSceneObject* sceneObject = editor->getSceneObjectFromID(selectedNode->getID());
//		sceneObject->GetCurrentAnim().m_loop = checkBox->isChecked();
	}

	CProperty* changedProp = 0;

	for (u32 i = 0; i < m_Properties.size(); i ++)	
		if (m_Properties[i].m_GUIElementEdit == checkBox)
		{
			changedProp = &m_Properties[i];
			break;
		}
	
	if (changedProp)
	{
		ISceneNode* selectedNode = editor->getSelectedNode();
		if (!selectedNode)
			return false;

		CSceneObject* sceneObject = editor->getSceneObjectFromID(selectedNode->getID());
		
		//@tcy
		if (sceneObject->m_UserData->getAttributeAsString("!GameType") == stringc("Bonus"))
		{
			if (changedProp->m_Name == stringw("HP"))
			{
				sceneObject->m_UserData->setAttribute("HP", true);
		 		sceneObject->m_UserData->setAttribute("WebPower", false);
				sceneObject->m_UserData->setAttribute("SkillPoint", false);
				editor->SetObjectEffectType(selectedNode, "bonus_green");
			}
			else if (changedProp->m_Name == stringw("WebPower"))
			{
				sceneObject->m_UserData->setAttribute("HP", false);
				sceneObject->m_UserData->setAttribute("WebPower", true);
				sceneObject->m_UserData->setAttribute("SkillPoint", false);
				editor->SetObjectEffectType(selectedNode, "bonus_blue");
			}
			else if (changedProp->m_Name == stringw("SkillPoint"))
			{
				sceneObject->m_UserData->setAttribute("HP", false);
				sceneObject->m_UserData->setAttribute("WebPower", false);
				sceneObject->m_UserData->setAttribute("SkillPoint", true);
				editor->SetObjectEffectType(selectedNode, "bonus_red");
			}
			
		}

		//checkBox works only for userData for now
		if (changedProp->m_bUserData)
		{
			editor->AddCommand(new CSetBoolAttributeCommand(selectedNode->getID(), stringc(changedProp->m_Name.c_str()), checkBox->isChecked()));
		}

		return true;
	}

	//check template properties
	for (u32 i = 0; i < m_TemplateProperties.size(); i ++)	
		if (m_TemplateProperties[i].m_GUIElementEdit == checkBox)
		{
			changedProp = &m_TemplateProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_TEMPLATE_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		IAttributes* pAttr = editor->m_GameTemplates[sel]->m_Attributes;

		pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), checkBox->isChecked());

		return true;
	}

	//check particle system properties
	for (u32 i = 0; i < m_PSProperties.size(); i ++)	
		if (m_PSProperties[i].m_GUIElementEdit == checkBox)
		{
			changedProp = &m_PSProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
		int sel = lb->getSelected();
		
		if (sel == -1) return false;

		lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

		int sel_ps = lb->getSelected();
		
		if (sel_ps == -1) return false;

		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		ISceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];
		pNode->serializeAttributes(pAttr);

		pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), checkBox->isChecked());

		pNode->deserializeAttributes(pAttr);

		pAttr->drop();
		return true;
	}

	//check affector properies
	for (u32 i = 0; i < m_AffectorProperties.size(); i ++)	
		if (m_AffectorProperties[i].m_GUIElementEdit == checkBox)
		{
			changedProp = &m_AffectorProperties[i];
			break;
		}
	
	if (changedProp)
	{
		IFpsParticleAffector* pAffector = getSelectedAffector();

		IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
		
		pAffector->serializeAttributes(pAttr);

		pAttr->setAttribute(stringc(changedProp->m_Name.c_str()).c_str(), checkBox->isChecked());

		pAffector->deserializeAttributes(0, pAttr);

		pAttr->drop();
		return true;
	}

	return false;
}
void CUserInterface::trySave()
{
	if (!editor->hasSceneFileName())
	{
		CGUIFileSaveDialog* dialog = new CGUIFileSaveDialog(L"Save Scene As...", g->guienv,
			g->guienv->getRootGUIElement(), FILE_SAVE_SCENE_DIALOG);
		dialog->drop();													
	}
	else
	{
		saveRecentFiles();
		editor->writeConfigOptions();
		editor->saveScene();
		editor->saveEffectPreset();
		
		if ( m_bQuitAfterSave )
		{
			g->device->closeDevice();
		}
	}
}

int CUserInterface::createProperty(stringw name, int type, s32 x, s32 y, IGUIElement* parent, array<CProperty>* pProperties)
{
	int height = 0;
	int propWidth = 190;
	IGUIElement* staticElem = 0;
	IGUIElement* edit = 0;
	IGUIElement* button = 0;
	bool fileDialog = false;
	stringw label = name;

	if ((name == L"Mesh") || (name.find(L"Texture") >= 0) || (name.find(L"File") >= 0))
		fileDialog = true;

	if (fileDialog)
	{
		propWidth = 170;	//20 pixels for file dialog btn
		button = g->guienv->addButton(rect<s32>(x + 170, y + 15, x + 190, y + 35), parent, PROP_FILE_BTN, L"...", L"Browse");
	}
	
	switch (type)
	{
		case EAT_INT:
			{
				if (name.c_str()[0] == L'$')
				{
					g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
					false, false, parent, 1);
					edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
					array<stringw> listArray = editor->getGameListArray(name.subString(1, name.size() - 1));
					for (u32 z = 0; z < listArray.size(); z ++)
						((IGUIComboBox*)edit)->addItem(listArray[z].c_str());
					height = 40;
				} 
				else
				if (name == L"MaterialType")
				{
					staticElem = g->guienv->addStaticText(name.c_str(), rect<s32>(x, y, x + 100, y + 20), 
						false, false, parent, 1);
					edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);				
					for (int z = 0; z < g->device->getVideoDriver()->getMaterialRendererCount(); z ++)
						((IGUIComboBox*)edit)->addItem(stringw(g->device->getVideoDriver()->getMaterialRendererName(z)).c_str());
					height = 40;				
				}
				else
				{
					staticElem = g->guienv->addStaticText(name.c_str(), rect<s32>(x, y, x + 100, y + 20), 
						false, false, parent, 1);
					edit = g->guienv->addEditBox(L"", rect<s32>(x + 100, y, x + propWidth, y + 20), true,
						parent, 1);
					height = 20;
				}
			}
			break;

		case EAT_FLOAT: 
			staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x + 100, y, x + propWidth, y + 20), true,
				parent, 1);
			height = 20;
			break;

		case EAT_STRING:
			if (name.c_str()[0] == L'$')
			{
				g->guienv->addStaticText(name.subString(1, name.size() - 1).c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
				edit = g->guienv->addComboBox(rect<s32>(x, y + 15, x + propWidth, y + 35), parent, 1);
				array<stringw> listArray = editor->getGameListArray(name.subString(1, name.size() - 1));
				for (u32 z = 0; z < listArray.size(); z ++)
					((IGUIComboBox*)edit)->addItem(listArray[z].c_str());
				height = 40;
			} 
			else
			{
				staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
					false, false, parent, 1);
				edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35), 
					true, parent, 1);
				height = 35;
			}
			break;

		case EAT_BOOL:
			staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), 
				false, false, parent, 1);
			edit = g->guienv->addCheckBox(false, rect<s32>(x + propWidth - 20, y, x + propWidth, y + 20), 
				parent, 1);
			height = 20;
			break;

		case EAT_VECTOR3D: 
			staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20),
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35),
				true, parent, 1);
			height = 35;
			break;

		case EAT_COLOR: 
			staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20),
				false, false, parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35),
				true, parent, 1);
			height = 35;
			break;

		case EAT_COLORF: 
			staticElem = g->guienv->addStaticText(label.c_str(), rect<s32>(x, y, x + 100, y + 20), false, false, 
				parent, 1);
			edit = g->guienv->addEditBox(L"", rect<s32>(x, y + 15, x + propWidth, y + 35), true,
				parent, 1);
			height = 35;
			break;
	}
	
	CProperty prop;

	prop.m_GUIElementStatic = staticElem;
	prop.m_GUIElementEdit = edit;
	prop.m_GUIElementButton = button;
	prop.m_Name = name;
	prop.m_Type = (E_ATTRIBUTE_TYPE)type;
	prop.m_bUserData = false;

	pProperties->push_back(prop);

	height += 5;	//spacing
	return height;
}

void CUserInterface::createSelectedPSProperties()
{
	if (m_PSTabs)
	{
		m_PSTabs->remove();
		m_PSTabs = NULL;
	}

	m_PSProperties.clear();
	m_AffectorProperties.clear();
	m_MatProperties.clear();

	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
	int sel = lb->getSelected();
	
	if (sel == -1) return;

	lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

	int sel_ps = lb->getSelected();
	
	if (sel_ps == -1) return;

	m_PSTabs = g->guienv->addTabControl(rect<s32>(0, 220, 198, 560), m_ToolsEffectsTab, false, false, TOOLS_PS_TABS);
	m_PSTabs->setTabHeight(20);
	m_PSTabs->addTab(L"Attr");
	m_PSTabs->addTab(L"Emit");
	m_PSTabs->addTab(L"Affect");
	m_PSTabs->addTab(L"Mat");
	m_PSAttrTab = m_PSTabs->getTab(0);
	m_PSEmitterTab = m_PSTabs->getTab(1);
	m_PSAffectorTab = m_PSTabs->getTab(2);
	m_PSMatTab = m_PSTabs->getTab(3);

	//affectors tab
	IGUIListBox* pListBox = g->guienv->addListBox(rect<s32>(5, 5, 190, 105), m_PSAffectorTab, TOOLS_ID_AFFECTORS_LIST, true);
	IGUIComboBox* pCombo = g->guienv->addComboBox(rect<s32>(5, 110, 140, 125), m_PSAffectorTab, TOOLS_ID_AFFECTORS_COMBO);
	pCombo->addItem(L"Attract");
	pCombo->addItem(L"FadeOut");
	pCombo->addItem(L"Gravity");
	pCombo->addItem(L"Rotate");
	pCombo->addItem(L"Scale");
	pCombo->addItem(L"Spin");
	g->guienv->addButton(rect<s32>(145, 110, 165, 125), m_PSAffectorTab, TOOLS_ID_ADD_AFFECTOR_BTN, L" + ", 0);
	g->guienv->addButton(rect<s32>(170, 110, 190, 125), m_PSAffectorTab, TOOLS_ID_REMOVE_AFFECTOR_BTN, L" - ", 0);

	IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
	IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];

	list<IFpsParticleAffector*> _affectors = ((IFpsParticleSystemSceneNode*)pNode)->getAffectors();
	core::list<IFpsParticleAffector*>::Iterator it = _affectors.begin();
	for(; it != _affectors.end(); it++)
	{
		switch ((*it)->getType())
		{
		case FPS_EPAT_ATTRACT:
			pListBox->addItem(L"Attraction");
			break;

		case FPS_EPAT_FADE_OUT:
			pListBox->addItem(L"FadeOut");
			break;

		case FPS_EPAT_GRAVITY:
			pListBox->addItem(L"Gravity");
			break;

		case FPS_EPAT_ROTATE:
			pListBox->addItem(L"Rotate");
			break;

		case FPS_EPAT_SIZE:
			pListBox->addItem(L"Scale");
			break;

		case FPS_EPAT_SPIN:
			pListBox->addItem(L"Spin");
			break;
		}
	}

	pNode->serializeAttributes(pAttr);

	int customY = 10;
	int firstCustomY = 10;

	IGUITab* pTab = m_PSAttrTab;

	for (u32 i=0; i < pAttr->getAttributeCount(); i++)
	{
		if (stringc(pAttr->getAttributeName(i)) == stringc("Id")) continue;
		if (stringc(pAttr->getAttributeName(i)) == stringc("Affector")) break;

		if (stringc(pAttr->getAttributeName(i)) == stringc("Emitter"))
		{
			pTab = m_PSEmitterTab;
			firstCustomY = customY;
			customY = 10;
		}

		customY += createProperty(pAttr->getAttributeName(i), 
			pAttr->getAttributeType(i), 5, customY, pTab, &m_PSProperties);
	}

	if (customY < firstCustomY) customY = firstCustomY;

	static const int k_ps_table_height = 280;

	rect<s32> pos = m_ToolsWindow->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + customY + k_ps_table_height;
	m_ToolsWindow->setRelativePosition(pos);

	pos = m_ToolsTabs->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + customY + k_ps_table_height;
	m_ToolsTabs->setRelativePosition(pos);

	pos = m_ToolsEffectsTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + customY + k_ps_table_height;
	m_ToolsEffectsTab->setRelativePosition(pos);

	pos = m_PSTabs->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + customY + k_ps_table_height;
	m_PSTabs->setRelativePosition(pos);

	pos = m_PSAttrTab->getRelativePosition();
	pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + customY + k_ps_table_height;
	m_PSAttrTab->setRelativePosition(pos);

	updateProperties(pAttr, &m_PSProperties);
	pAttr->drop();

	//create material props
	pAttr = g->device->getFileSystem()->createEmptyAttributes();
	
	SMaterial mat = pNode->getMaterial(0);
	ITexture *pTexture = mat.getTexture(0);
	if (pTexture)
	{
		pAttr->addString("Texture", pTexture->getName().getPath().c_str());
	}
	else
	{
		pAttr->addString("Texture", "");
	}

	pAttr->addString("$SpriteFrameName",pNode->getSpriteFrameName().c_str());

	pAttr->addInt("MaterialType", mat.MaterialType);

	customY = 10;

	for (u32 i=0; i < pAttr->getAttributeCount(); i++)
	{
		customY += createProperty(pAttr->getAttributeName(i), 
			pAttr->getAttributeType(i), 5, customY, m_PSMatTab, &m_MatProperties);
	}

	updateProperties(pAttr, &m_MatProperties);

	pAttr->drop();
}

//populate current prop. values from object when edited	
void CUserInterface::updateProperties(IAttributes* pAttr, array<CProperty>* pProperties)
{
	stringw valueStr;

	for (u32 i = 0; i < pProperties->size(); i ++)
	{
		//standart types first
		valueStr = "";
		
		switch ((*pProperties)[i].m_Type)
		{
			case EAT_INT:
				if ((*pProperties)[i].m_Name.c_str()[0] == L'$')
				{
					((IGUIComboBox*)(*pProperties)[i].m_GUIElementEdit)->setSelected(pAttr->getAttributeAsInt( stringc((*pProperties)[i].m_Name.c_str()).c_str()) );
					continue;
				}
				else
				if ((*pProperties)[i].m_Name == L"MaterialType")
				{
					if ((*pProperties)[i].m_GUIElementEdit)
						((IGUIComboBox*)(*pProperties)[i].m_GUIElementEdit)->setSelected(pAttr->getAttributeAsInt( stringc((*pProperties)[i].m_Name.c_str()).c_str()));
					continue;
				}

				valueStr = stringw(pAttr->getAttributeAsInt( stringc((*pProperties)[i].m_Name.c_str()).c_str()));
				break;

			case EAT_BOOL:
				if ((*pProperties)[i].m_GUIElementEdit)
					((IGUICheckBox*)(*pProperties)[i].m_GUIElementEdit)->setChecked(
					pAttr->getAttributeAsBool( stringc((*pProperties)[i].m_Name.c_str()).c_str()));
				break;					
			
			case EAT_FLOAT: 
				valueStr = stringw(pAttr->getAttributeAsFloat(stringc((*pProperties)[i].m_Name.c_str()).c_str()));
				break;				
			
			case EAT_VECTOR3D:
				{
					vector3df vec = pAttr->getAttributeAsVector3d( stringc((*pProperties)[i].m_Name.c_str()).c_str() );
					valueStr = vector3DToString(&vec, 5);
				}
				break;

			case EAT_STRING: 
				if ((*pProperties)[i].m_Name.c_str()[0] == L'$')
				{
					valueStr = pAttr->getAttributeAsStringW(stringc((*pProperties)[i].m_Name.c_str()).c_str());

					array<stringw> listArray = editor->getGameListArray((*pProperties)[i].m_Name.subString(1, (*pProperties)[i].m_Name.size() - 1));
					for (u32 z = 0; z < listArray.size(); z ++)
					{
						if (listArray[z] == stringw(valueStr))
						{
							((IGUIComboBox*)(*pProperties)[i].m_GUIElementEdit)->setSelected(z);
							break;
						}
					}

					continue;
				}
				else
				{
					valueStr = pAttr->getAttributeAsStringW(stringc((*pProperties)[i].m_Name.c_str()).c_str());
				}
				break;

			case EAT_COLOR:
				{
					SColor color = pAttr->getAttributeAsColor(stringc((*pProperties)[i].m_Name.c_str()).c_str());
					valueStr = colorToString(&color);
				}
				break;
		}

		if ((*pProperties)[i].m_GUIElementEdit)
		{
			(*pProperties)[i].m_GUIElementEdit->setText(valueStr.c_str());
		}
	}
}

IFpsParticleAffector* CUserInterface::getSelectedAffector()
{
	IGUIListBox* lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_EFFECTS_LIST, true);
	int sel = lb->getSelected();
	
	if (sel == -1) return NULL;

	lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_PS_LIST, true);

	int sel_ps = lb->getSelected();
	
	if (sel_ps == -1) return NULL;

	IFpsParticleSystemSceneNode* pNode = editor->m_Effects[sel]->m_ParticleSystems[sel_ps];
	list<IFpsParticleAffector*> _affectors = pNode->getAffectors();
	
	lb = (IGUIListBox*)m_ToolsWindow->getElementFromId(TOOLS_ID_AFFECTORS_LIST, true);
	sel = lb->getSelected();

	IFpsParticleAffector* pAffector = NULL;
	core::list<IFpsParticleAffector*>::Iterator it = _affectors.begin();

	int index = 0;
	for(; it != _affectors.end(); it++)
	{
		if (index == sel)
		{
			pAffector = (*it);
			break;
		}

		index++;
	}

	return pAffector;
}

void CUserInterface::createSelectedAffectorProperties()
{
	for (u32 i=0; i < m_AffectorProperties.size(); i++)
	{
		if (m_AffectorProperties[i].m_GUIElementStatic) m_AffectorProperties[i].m_GUIElementStatic->remove();
		if (m_AffectorProperties[i].m_GUIElementEdit) m_AffectorProperties[i].m_GUIElementEdit->remove();
		if (m_AffectorProperties[i].m_GUIElementButton) m_AffectorProperties[i].m_GUIElementButton->remove();
	}

	m_AffectorProperties.clear();

	IFpsParticleAffector* pAffector = getSelectedAffector();

	if (pAffector == NULL) return;

	IAttributes* pAttr = g->device->getFileSystem()->createEmptyAttributes();
	pAffector->serializeAttributes(pAttr);

	int customY = 135;

	for (u32 i=0; i < pAttr->getAttributeCount(); i++)
	{
		customY += createProperty(pAttr->getAttributeName(i), 
			pAttr->getAttributeType(i), 5, customY, m_PSAffectorTab, &m_AffectorProperties);
	}

	updateProperties(pAttr, &m_AffectorProperties);

	pAttr->drop();

	//E_PARTICLE_AFFECTOR_TYPE type = pAffector->getType();

	//int customY = 135;
	//int x = 5;
	//int propWidth = 190;

	//if (type == EPAT_ATTRACT)
	//{
	//	g->guienv->addStaticText(L"Point", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	vector3df point = ((IParticleAttractionAffector*) pAffector)->getPoint();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_ATTRACT_POINT);
	//	edit->setText(vector3DToString(&point, 5).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Attract", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);

	//	bool bAttract = ((IParticleAttractionAffector*) pAffector)->getAttract();
	//	IGUICheckBox* checkBox = g->guienv->addCheckBox(bAttract, rect<s32>(x + propWidth - 20, customY, x + propWidth, customY + 20), m_PSAffectorTab, TOOLS_ID_AFFECTOR_ATTRACT_CHECKBOX);
	//	customY += 25;

	//	g->guienv->addStaticText(L"Affect X", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);

	//	bool bAffectX = ((IParticleAttractionAffector*) pAffector)->getAffectX();
	//	checkBox = g->guienv->addCheckBox(bAffectX, rect<s32>(x + propWidth - 20, customY, x + propWidth, customY + 20), m_PSAffectorTab, TOOLS_ID_AFFECTOR_ATTRACT_AFFECT_X);
	//	customY += 25;

	//	g->guienv->addStaticText(L"Affect Y", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);

	//	bool bAffectY = ((IParticleAttractionAffector*) pAffector)->getAffectY();
	//	checkBox = g->guienv->addCheckBox(bAffectY, rect<s32>(x + propWidth - 20, customY, x + propWidth, customY + 20), m_PSAffectorTab, TOOLS_ID_AFFECTOR_ATTRACT_AFFECT_Y);
	//	customY += 25;

	//	g->guienv->addStaticText(L"Affect Z", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);

	//	bool bAffectZ = ((IParticleAttractionAffector*) pAffector)->getAffectZ();
	//	checkBox = g->guienv->addCheckBox(bAffectZ, rect<s32>(x + propWidth - 20, customY, x + propWidth, customY + 20), m_PSAffectorTab, TOOLS_ID_AFFECTOR_ATTRACT_AFFECT_Z);
	//	customY += 25;
	//}

	//if (type == EPAT_FADE_OUT)
	//{
	//	g->guienv->addStaticText(L"FadeOut Time", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 time = ((IParticleFadeOutAffector*) pAffector)->getFadeOutTime();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_FADEOUT_TIME);
	//	edit->setText(stringw(time).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Target Color", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	SColor color = ((IParticleFadeOutAffector*) pAffector)->getTargetColor();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_FADEOUT_COLOR);
	//	edit->setText(colorToString(&color).c_str());
	//	customY += 25;
	//}

	//if (type == EPAT_GRAVITY)
	//{
	//	g->guienv->addStaticText(L"Gravity", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	vector3df gravity = ((IParticleGravityAffector*) pAffector)->getGravity();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_GRAVITY);
	//	edit->setText(vector3DToString(&gravity, 5).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Time Force Lost", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 time = ((IParticleGravityAffector*) pAffector)->getTimeForceLost();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_GRAVITY_TIME);
	//	edit->setText(stringw(time).c_str());
	//	customY += 25;
	//}

	//if (type == EPAT_ROTATE)
	//{
	//	g->guienv->addStaticText(L"Pivot Point", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	vector3df point = ((IParticleRotationAffector*) pAffector)->getPivotPoint();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_ROTATION_POINT);
	//	edit->setText(vector3DToString(&point, 5).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Speed", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	vector3df speed = ((IParticleRotationAffector*) pAffector)->getSpeed();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_ROTATION_SPEED);
	//	edit->setText(vector3DToString(&speed, 5).c_str());
	//	customY += 25;
	//}

	//if (type == EPAT_SIZE)
	//{
	//	g->guienv->addStaticText(L"Fade For Time", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 fade_time = ((IParticleSizeAffector*) pAffector)->getFadeForTime();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SIZE_FADE_TIME);
	//	edit->setText(stringw(fade_time).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Grow For Time", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 grow_time = ((IParticleSizeAffector*) pAffector)->getGrowForTime();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SIZE_GROW_TIME);
	//	edit->setText(stringw(grow_time).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Target Size", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 target_size = ((IParticleSizeAffector*) pAffector)->getTargetSize();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SIZE_TARGET);
	//	edit->setText(stringw(target_size).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Variation", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 variation = ((IParticleSizeAffector*) pAffector)->getVariation();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SIZE_VARIATION);
	//	edit->setText(stringw(variation).c_str());
	//	customY += 25;
	//}

	//if (type == EPAT_SPIN)
	//{
	//	g->guienv->addStaticText(L"Spin Time", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 time = ((IParticleSpinAffector*) pAffector)->getSpinTime();
	//	IGUIEditBox* edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SPIN_TIME);
	//	edit->setText(stringw(time).c_str());
	//	customY += 25;

	//	g->guienv->addStaticText(L"Variation", rect<s32>(x, customY, x + propWidth, customY + 20), false, true, m_PSAffectorTab);
	//	customY += 20;

	//	f32 variation = ((IParticleSpinAffector*) pAffector)->getVariation();
	//	edit = g->guienv->addEditBox(L"", rect<s32>(x, customY, x + propWidth, customY + 20), true, m_PSAffectorTab, TOOLS_ID_AFFECTOR_SPIN_VARIATION);
	//	edit->setText(stringw(variation).c_str());
	//	customY += 25;
	//}
}
void CUserInterface::unselectButtons()
{
	m_MovePushButton->setPressed(false);
	m_MoveLocalPushButton->setPressed(false);
	m_RotatePushButton->setPressed(false);
	m_RotateLocalPushButton->setPressed(false);
	m_ScalePushButton->setPressed(false);
	m_ModifyPushButton->setPressed(false);
	m_SetCameraButton->setPressed(false);
}

void CUserInterface::createFPExporterWindow()
{
	if(m_PFExporterWindow)
		m_PFExporterWindow->remove();

	std::vector<RoomMapInfo*>& roomMaps = PFExporter::GetRoomMaps();
	int mapNum = roomMaps.size();

	int winW = 500;
	int winH = mapNum*20+120;

	rect<s32> r( 300 , 100 , 300+winW , 100+winH);

	m_PFExporterWindow = g->guienv->addWindow(r, false, L"Export Illumination Maps", 0, WND_ID_PFEXPORTER_WIN);

	int x = 10;
	int y = 30;

	for(int i=0; i<mapNum; ++i)
	{
		roomMaps[i]->NeedExport = false;
		irr::core::stringw label(roomMaps[i]->FileName.c_str());
		g->guienv->addStaticText( label.c_str(), rect<s32>(x+40, y, x + 240, y + 20), 
				false, false, m_PFExporterWindow, 1);
		g->guienv->addCheckBox(false, rect<s32>(x + 10, y, x + 35, y + 20), 
			m_PFExporterWindow, PFEXPORT_CHECKBOX_0+i)->setChecked(false);
		y+=20;
	}

	int btW = 100;		
	int btX = 10;

	IGUIButton* btCheckAll = g->guienv->addButton(rect<s32>(btX, winH-30, btX+btW, winH-10), m_PFExporterWindow, PFEXPORT_BT_CHECK_ALL, L"Sel/UnSel All");
	btX+=btW+10;
	IGUIButton* btExport = g->guienv->addButton(rect<s32>(btX, winH-30, btX+btW, winH-10), m_PFExporterWindow, PFEXPORT_BT_EXPORT, L"Export");
			
	btCheckAll->setIsPushButton(true);

	if(mapNum==0)
	{
		btCheckAll->setEnabled(false);
		btExport->setEnabled(false);
	}

	int startx = 10;
	int starty = winH-80;	
	g->guienv->addStaticText( L"MinValue", rect<s32>(startx, starty, startx+50, starty+20), 
				false, false, m_PFExporterWindow, 1);
	startx+=50;
	IGUISpinBox* spMinValue =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+40, starty+20), true, m_PFExporterWindow,PFEXPORT_EDIT_MIN_VALUE);
	startx+=50;
	int min = PFExporter::GetMinValue();
	spMinValue->setValue(min);
	spMinValue->setDecimalPlaces(0);

	g->guienv->addStaticText( L"MaxValue", rect<s32>(startx, starty, startx+50, starty+20), 
				false, false, m_PFExporterWindow, 1);
	startx+=50;
	IGUISpinBox* spMaxValue =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+40, starty+20), true,m_PFExporterWindow,PFEXPORT_EDIT_MAX_VALUE);
	startx+=50;
	int max = PFExporter::GetMaxValue();
	spMaxValue->setValue(max);
	spMaxValue->setDecimalPlaces(0);

	g->guienv->addStaticText( L"Offset", rect<s32>(startx, starty, startx+50, starty+20), 
				false, false, m_PFExporterWindow, 1);
	startx+=50;
	IGUISpinBox* spOffValue =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+40, starty+20), true,m_PFExporterWindow,PFEXPORT_EDIT_OFFSET_VALUE);
	startx+=50;
	int off = PFExporter::GetOffset();
	spOffValue->setValue(off);
	spOffValue->setDecimalPlaces(0);

	float sr,sg,sb;
	PFExporter::GetRGBScale(sr,sg,sb);
	g->guienv->addStaticText( L"RGB", rect<s32>(startx, starty, startx+30, starty+20), 
				false, false, m_PFExporterWindow, 1);
	startx+=30;
	IGUISpinBox* spR =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+50, starty+20), true,m_PFExporterWindow,PFEXPORT_EDIT_SR);
	startx+=50;	
	spR->setValue(sr);
	spR->setDecimalPlaces(2);
	spR->setStepSize(0.1f);
	
	IGUISpinBox* spG =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+50, starty+20), true,m_PFExporterWindow,PFEXPORT_EDIT_SG);
	startx+=50;	
	spG->setValue(sg);
	spG->setDecimalPlaces(2);
	spG->setStepSize(0.1f);
	
	IGUISpinBox* spB =g->guienv->addSpinBox(L"",rect<s32>(startx, starty, startx+50, starty+20), true,m_PFExporterWindow,PFEXPORT_EDIT_SB);
	startx+=50;	
	spB->setValue(sb);
	spB->setDecimalPlaces(2);
	spB->setStepSize(0.1f);

	btX+=btW+10;
	g->guienv->addStaticText( L"TileSize", rect<s32>(btX, winH-30, btX+50, winH-10), 
				false, false, m_PFExporterWindow, 1);
	btX+=50;
	IGUISpinBox* spTileSize =g->guienv->addSpinBox(L"",rect<s32>(btX, winH-30, btX+60, winH-10), true,m_PFExporterWindow,PFEXPORT_EDIT_TILE_SIZE);
	int ts = PFExporter::GetTileSize();
	spTileSize->setValue(ts);
	spTileSize->setDecimalPlaces(0);
	btX+=80;
	g->guienv->addStaticText( L"TileSizeZ", rect<s32>(btX, winH-30, btX+50, winH-10), 
				false, false, m_PFExporterWindow, 1);
	btX+=50;
	IGUISpinBox* spTileSizeZ =g->guienv->addSpinBox(L"",rect<s32>(btX, winH-30, btX+60, winH-10), true,m_PFExporterWindow,PFEXPORT_EDIT_TILE_SIZE_Z);
	int tsz = PFExporter::GetTileSizeZ();
	spTileSizeZ->setValue(tsz);
	spTileSizeZ->setDecimalPlaces(0);


	
	if(mapNum>0)
	{	
		g->guienv->addStaticText( L"The process is very slow, please wait in patience.", rect<s32>(10, winH-50, 500, winH-35), 
			false, false, m_PFExporterWindow, 1);
	}

	m_PFExporterWindow->setVisible(true);	
}

void CUserInterface::FPExportWinButtonPressed(const SEvent& event)
{
	s32 id = event.GUIEvent.Caller->getID();
	std::vector<RoomMapInfo*>& roomMaps = PFExporter::GetRoomMaps();
	int mapNum = roomMaps.size();
	IGUIButton* button = (IGUIButton*)event.GUIEvent.Caller;

	switch(id)
	{
	case PFEXPORT_BT_CHECK_ALL:
		{						
			bool checked = button->isPressed();			

			for(int i=0; i<mapNum; i++)
			{
				IGUICheckBox* cb = (IGUICheckBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_CHECKBOX_0+i, false);
				cb->setChecked(checked);
				roomMaps[i]->NeedExport = checked;
			}
		}
		break;

	case PFEXPORT_BT_EXPORT:
		{				
			IGUISpinBox* sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_TILE_SIZE, false);
			int tileSize = sp->getValue();
			PFExporter::SetTileSize(tileSize);

			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_TILE_SIZE_Z, false);
			int tileSizeZ = sp->getValue();
			PFExporter::SetTileSizeZ(tileSizeZ);

			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_MIN_VALUE, false);
			int value = sp->getValue();
			PFExporter::SetMinValue(value);

			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_MAX_VALUE, false);
			value = sp->getValue();
			PFExporter::SetMaxValue(value);

			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_OFFSET_VALUE, false);
			value = sp->getValue();
			PFExporter::SetOffset(value);

			float sr,sg,sb;
			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_SR, false);
			sr = sp->getValue();
			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_SG, false);
			sg = sp->getValue();
			sp = (IGUISpinBox*)m_PFExporterWindow->getElementFromId(PFEXPORT_EDIT_SB, false);
			sb = sp->getValue();
			PFExporter::SetRGBScale(sr,sg,sb);


			for(int i=0; i<mapNum; i++)
			{
				if(roomMaps[i]->NeedExport)
				{
					PFExporter::Export(g->sceneManager, i, tileSize, tileSizeZ);
				}
			}
		}
		break;
	}
}

void CUserInterface::FPExportWinCheckBoxChanged(const SEvent& event)
{	
	std::vector<RoomMapInfo*>& roomMaps = PFExporter::GetRoomMaps();
	int mapNum = roomMaps.size();
	if(mapNum==0)
		return;

	s32 id = event.GUIEvent.Caller->getID();
	int i = id-PFEXPORT_CHECKBOX_0;
	if(i<0 || i>=mapNum)
		return;

	IGUICheckBox* cb = (IGUICheckBox*)event.GUIEvent.Caller;
	bool checked = cb->isChecked();
	roomMaps[i]->NeedExport = checked;
}

void CUserInterface::createLevelProprtiesWindow()
{
	rect<s32> r( 300 , 300 , 500 , 440);
	m_LevelProperties = g->guienv->addWindow( r , false , L"LevelProperties" , 0 , WND_ID_LEVEL_PROPERTIES);
	rect<s32> r1(  10 , 30 , r.getWidth() - 10 , r.getHeight() - 10);
	//IGUITable* table = g->guienv->addTable( r1 , m_LevelProperties , -1 , true ); 
	//table->addColumn(L"Properties");
	//table->setColumnWidth( 0 , r1.getWidth() * 3 / 10 );
	//table->addColumn(L"Value");
	//table->setColumnWidth( 1 , r1.getWidth() * 7 / 10 );
	//table->addRow(0);
	//table->setCellText( 0 , 0 , L"Music");
	//table->addRow(1);
	//table->setCellText( 1 , 0 , L"Texts");
	//table->addRow(2);
	//table->setCellText( 2 , 0 , L"Loading");

	rect<s32> r2(  10 , 30 , r1.getWidth() - 10 , r1.getHeight() - 10);
	IGUITabControl * tab = g->guienv->addTabControl(r1 , m_LevelProperties , false , true );
	IGUITab* t1 = tab->addTab(L"Music");
	//add static text 
	rect<s32> r3(  10 , 30 , r1.getWidth() * 3 / 4 , r1.getHeight() - 10);
	g->guienv->addEditBox(L"File" , r3 , true , t1 );
	
	rect<s32> r4(  r1.getWidth() * 3 / 4 , 30 , r1.getWidth() , r1.getHeight() - 10);
	g->guienv->addButton(r4 , t1 , WND_ID_OPEN_MUSIC_FILE , L"..." , L"Open dialog");
	//add  button to open file load dialog 

	IGUITab* t2 = tab->addTab(L"Texts");	

	g->guienv->addEditBox(L"File" , r3 , true , t2 );		
	g->guienv->addButton(r4 , t2 , WND_ID_OPEN_TEXT_FILE , L"..." , L"Open dialog");

	IGUITab* t3 = tab->addTab(L"Loading");	
	g->guienv->addEditBox(L"File" , r3 , true , t3 );		
	g->guienv->addButton(r4 , t3 , WND_ID_OPEN_LOADING_FILE , L"..." , L"Open dialog");

	m_LevelProperties->setVisible(false);
}

bool CUserInterface::IsEffectsTabSelected()
{
	 return (m_ToolsTabs->getActiveTab() == 2);
}

void CUserInterface::HideRestoreWindows(bool hide)
{
	if(hide)
	{
		m_windowVisibles.clear();
		m_windowVisibles.push_back(m_ToolsWindow->isVisible());
		m_windowVisibles.push_back(m_PropertiesWindow->isVisible());
		m_windowVisibles.push_back(m_SceneGraphWindow->isVisible());
		m_windowVisibles.push_back(m_HistoryWindow->isVisible());
		m_windowVisibles.push_back(m_LevelProperties->isVisible());

		m_windowVisibles.push_back(m_CinematicEditor.m_Active);

		m_ToolsWindow->setVisible(false);
		m_PropertiesWindow->setVisible(false);
		m_SceneGraphWindow->setVisible(false);
		m_HistoryWindow->setVisible(false);
		m_LevelProperties->setVisible(false);

		if( m_CinematicEditor.m_Active )
		{
			m_CinematicEditor.SetVisible(false);
		}
	}
	else
	{
		m_ToolsWindow->setVisible(m_windowVisibles[0]);
		m_PropertiesWindow->setVisible(m_windowVisibles[1]);
		m_SceneGraphWindow->setVisible(m_windowVisibles[2]);
		m_HistoryWindow->setVisible(m_windowVisibles[3]);
		m_LevelProperties->setVisible(m_windowVisibles[4]);

		if( m_windowVisibles[5] )
		{
			m_CinematicEditor.SetVisible(true);
		}
		m_windowVisibles.clear();
	}
}

int CUserInterface::loadRecentFiles()
{
	DEBUG_OUT("reading editor recent files!!!\n");

	m_recentFiles.clear();

	//irr::core::stringc workDir = g->device->getFileSystem()->getWorkingDirectory();

	irr::core::stringc filePathName = m_startupDir+ "/editor_recent.xml";
	IXMLReader* xml = g->device->getFileSystem()->createXMLReader(filePathName.c_str());

	if (!xml)
	{
		DEBUG_OUT("editor_recent.xml isn't exists!!!\n");
		return 1;
	}

	while (xml->read())
	{
		switch(xml->getNodeType())
		{
			case EXN_ELEMENT:
			{
				if (!wcscmp(L"RecentFile", xml->getNodeName()))
				{
					core::stringw recentFile = xml->getAttributeValue(L"value");
					m_recentFiles.push_back( recentFile );
					DEBUG_OUT("recentFile %s\n", recentFile.c_str());
				}
			}
			break;
		}
	}

	xml->drop();

	return 0;
}

int CUserInterface::saveRecentFiles()
{	
	irr::core::stringc configPath = m_startupDir + "\\editor_recent.xml";
	IXMLWriter* xml = g->device->getFileSystem()->createXMLWriter(configPath.c_str());

	if (!xml)
	{
		DEBUG_OUT("can't write editor_recent.xml!!!\n");
		return 1;
	}
	
	xml->writeXMLHeader();

	int count = m_recentFiles.size();
	for(int i= count -1;i>=0;i--)
	{
		xml->writeElement(L"RecentFile", true, L"value", m_recentFiles[i].c_str() );	
		xml->writeLineBreak();
	}

	return 0;
}

